//////////////////////////////////////////////////////////////////////////
public:
	/// <summary>
	/// <malloc> wrapper.
	/// If there is no enough memory, the function
	/// (as well as other OpenCV functions that call Alloc)
	/// raises an error.
	/// </summary>
	/// <param name="size"></param>
	/// <returns></returns>
	static IntPtr Alloc(size_t size)
	{
		return IntPtr(cvAlloc(size));
	}

	/// <summary>
	/// <free> wrapper.
	/// Here and further all the memory releasing functions
	/// (that all call Free) take double pointer in order to
	/// to clear pointer to the data after releasing it.
	/// Passing pointer to IntPtr.Zero pointer is Ok: nothing happens in this case
	/// </summary>
	/// <param name="ptr"></param>
	static void Free_(IntPtr ptr)
	{
		return cvFree_(ptr.ToPointer());
	}

	/// <summary>
	/// cvFree
	/// </summary>
	static void Free(IntPtr ptr) 
	{
		cvFree((void**)ptr.ToPointer()); 
	}

	/// <summary>
	/// Allocates and initializes IplImage header
	/// </summary>
	/// <param name="size"></param>
	/// <param name="depth"></param>
	/// <param name="channels"></param>
	/// <returns></returns>

	static IntPtr CreateImageHeader(NAMESPACE::Size2D32s size, PixelDepth depth, int channels)
	{
		return IntPtr(cvCreateImageHeader(cvSize(size.Width, size.Height), (int)depth, channels));
	}

	/// <summary>
	/// Inializes IplImage header
	/// </summary>
	/// <param name="image"></param>
	/// <param name="size"></param>
	/// <param name="depth"></param>
	/// <param name="channels"></param>
	/// <param name="origin"></param>
	/// <param name="align"></param>
	/// <returns></returns>
	static IntPtr InitImageHeader(IntPtr image, NAMESPACE::Size2D32s size, PixelDepth depth, int channels, ImageOrigin origin, ImageAlign align)
	{
		return IntPtr(cvInitImageHeader((IplImage*)image.ToPointer(), cvSize(size.Width, size.Height), (int)depth, channels, (int)origin, (int)align));
	}

	/// <summary>
	/// Inializes IplImage header
	/// </summary>
	/// <param name="image"></param>
	/// <param name="size"></param>
	/// <param name="depth"></param>
	/// <param name="channels"></param>
	/// <param name="origin"></param>
	/// <returns></returns>
	static IntPtr InitImageHeader(IntPtr image, NAMESPACE::Size2D32s size, PixelDepth depth, int channels, ImageOrigin origin)
	{
		return IntPtr(cvInitImageHeader((IplImage*)image.ToPointer(), cvSize(size.Width, size.Height), (int)depth, channels, (int)origin));
	}

	/// <summary>
	/// Inializes IplImage header
	/// </summary>
	/// <param name="image"></param>
	/// <param name="size"></param>
	/// <param name="depth"></param>
	/// <param name="channels"></param>
	/// <returns></returns>
	static IntPtr InitImageHeader(IntPtr image, NAMESPACE::Size2D32s size, PixelDepth depth, int channels)
	{
		return IntPtr(cvInitImageHeader((IplImage*)image.ToPointer(), cvSize(size.Width, size.Height), (int)depth, channels));
	}

	/// <summary>
	/// Creates IPL image (header and data)
	/// </summary>
	/// <param name="size"></param>
	/// <param name="depth"></param>
	/// <param name="channels"></param>
	/// <returns></returns>
	static IntPtr CreateImage(NAMESPACE::Size2D32s size, PixelDepth depth, int channels)
	{
		return IntPtr(cvCreateImage(cvSize(size.Width, size.Height), (int)depth, channels));
	}

	/// <summary>
	/// Releases (i.e. deallocates) IPL image header
	/// </summary>
	/// <param name="image"></param>
	static void ReleaseImageHeader(IntPtr image)
	{
		cvReleaseImageHeader((IplImage**)image.ToPointer());
	}

	/// <summary>
	/// Releases IPL image header and data
	/// </summary>
	/// <param name="image"></param>
	static void ReleaseImage(IntPtr image)
	{
		cvReleaseImage((IplImage**)image.ToPointer());
	}

	/// <summary>
	/// Creates a copy of IPL image (widthStep may differ)
	/// </summary>
	/// <param name="image"></param>
	/// <returns></returns>
	static IntPtr CloneImage(IntPtr image)
	{
		return IntPtr(cvCloneImage((IplImage*)image.ToPointer()));
	}

	/// <summary>
	/// Sets a Channel Of Interest (only a few functions support COI) -
	/// use Copy to extract the selected channel and/or put it back
	/// </summary>
	/// <param name="image"></param>
	/// <param name="coi"></param>
	static void SetImageCOI(IntPtr image, int coi)
	{
		cvSetImageCOI((IplImage*)image.ToPointer(), coi);
	}

	/// <summary>
	/// Retrieves image Channel Of Interest
	/// </summary>
	/// <param name="image"></param>
	/// <returns></returns>
	static int GetImageCOI(IntPtr image)
	{
		return cvGetImageCOI((IplImage*)image.ToPointer());
	}

	/// <summary>
	/// Sets image ROI (region of interest) (COI is not changed)
	/// </summary>
	/// <param name="image"></param>
	/// <param name="rect"></param>
	static void SetImageROI(IntPtr image, NAMESPACE::Rect rect)
	{
		cvSetImageROI((IplImage*)image.ToPointer(), *(CvRect*)&rect);
	}

	/// <summary>
	/// Resets image ROI and COI
	/// </summary>
	/// <param name="image"></param>
	static void ResetImageROI(IntPtr image)
	{
		cvResetImageROI((IplImage*)image.ToPointer());
	}

	/// <summary>
	/// Retrieves image ROI
	/// </summary>
	/// <param name="image"></param>
	/// <returns></returns>
	static NAMESPACE::Rect GetImageROI(IntPtr image)
	{
		return *(NAMESPACE::Rect*)&cvGetImageROI((IplImage*)image.ToPointer());
	}

	/// <summary>
	/// Allocates and initalizes CvMat header
	/// </summary>
	/// <param name="rows"></param>
	/// <param name="cols"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr CreateMatHeader(int rows, int cols, MatFlag type)
	{
		return IntPtr(cvCreateMatHeader(rows, cols, (int)type));
	}

	/// <summary>
	/// Initializes CvMat header
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="rows"></param>
	/// <param name="cols"></param>
	/// <param name="type"></param>
	/// <param name="data"></param>
	/// <param name="step"></param>
	/// <returns></returns>
	static IntPtr InitMatHeader(IntPtr mat, int rows, int cols, MatFlag type, IntPtr data, int step)
	{
		return IntPtr(cvInitMatHeader((CvMat*)mat.ToPointer(), rows, cols, (int)type, data.ToPointer(), step));
	}

	/// <summary>
	/// Initializes CvMat header
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="rows"></param>
	/// <param name="cols"></param>
	/// <param name="type"></param>
	/// <param name="data"></param>
	/// <returns></returns>
	static IntPtr InitMatHeader(IntPtr mat, int rows, int cols, MatFlag type, IntPtr data)
	{
		return IntPtr(cvInitMatHeader((CvMat*)mat.ToPointer(), rows, cols, (int)type, data.ToPointer()));
	}

	/// <summary>
	/// Initializes CvMat header
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="rows"></param>
	/// <param name="cols"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr InitMatHeader(IntPtr mat, int rows, int cols, MatFlag type)
	{
		return IntPtr(cvInitMatHeader((CvMat*)mat.ToPointer(), rows, cols, (int)type));
	}

	/// <summary>
	/// Allocates and initializes CvMat header and allocates data
	/// </summary>
	/// <param name="rows"></param>
	/// <param name="cols"></param>
	/// <param name="type"></param>
	/// <returns></returns>

	static IntPtr CreateMat(int rows, int cols, MatFlag type)
	{
		return IntPtr(cvCreateMat(rows, cols, (int)type));
	}

	/// <summary>
	/// Releases CvMat header and deallocates matrix data
	/// (reference counting is used for data)
	/// </summary>
	/// <param name="mat"></param>
	static void ReleaseMat(IntPtr mat)
	{
		cvReleaseMat((CvMat**)mat.ToPointer());
	}

	/// <summary>
	/// Creates an exact copy of the input matrix (except, may be, step value)
	/// </summary>
	/// <param name="mat"></param>
	/// <returns></returns>
	static IntPtr CloneMat(IntPtr mat)
	{
		return IntPtr(cvCloneMat((CvMat*)mat.ToPointer()));
	}

	/// <summary>
	/// Makes a new matrix from <rect> subrectangle of input array.
	/// No data is copied
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="submat"></param>
	/// <param name="rect"></param>
	/// <returns></returns
	static IntPtr GetSubRect(IntPtr arr, IntPtr submat, NAMESPACE::Rect rect)
	{
		return IntPtr(cvGetSubRect(arr.ToPointer(), (CvMat*)submat.ToPointer(), *(CvRect*)&rect));
	}

	/// <summary>
	/// Makes a new matrix from <rect> subrectangle of input array.
	/// No data is copied
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="submat"></param>
	/// <param name="rect"></param>
	/// <returns></returns>
	static IntPtr GetSubArr(IntPtr arr, IntPtr submat, NAMESPACE::Rect rect)
	{
		return IntPtr(cvGetSubArr(arr.ToPointer(), (CvMat*)submat.ToPointer(), *(CvRect*)&rect));
	}

	/// <summary>
	/// Selects row span of the input array: arr(start_row:delta_row:end_row,:)
	/// (end_row is not included into the span).
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="submat"></param>
	/// <param name="start_row"></param>
	/// <param name="end_row"></param>
	/// <param name="delta_row"></param>
	/// <returns></returns>
	static IntPtr GetRows(IntPtr arr, IntPtr submat, int start_row, int end_row, int delta_row)
	{
		return IntPtr(cvGetRows(arr.ToPointer(), (CvMat*)submat.ToPointer(), start_row, end_row, delta_row));
	}

	/// <summary>
	/// Selects row span of the input array: arr(start_row:delta_row:end_row,:)
	/// (end_row is not included into the span).
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="submat"></param>
	/// <param name="start_row"></param>
	/// <param name="end_row"></param>
	/// <returns></returns>
	static IntPtr GetRows(IntPtr arr, IntPtr submat, int start_row, int end_row)
	{
		return IntPtr(cvGetRows(arr.ToPointer(), (CvMat*)submat.ToPointer(), start_row, end_row));
	}

	/// <summary>
	/// Selects column span of the input array: arr(:,start_col:end_col)
	/// (end_col is not included into the span)
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="submat"></param>
	/// <param name="start_col"></param>
	/// <param name="end_col"></param>
	/// <returns></returns>
	static IntPtr GetCols(IntPtr arr, IntPtr submat, int start_col, int end_col)
	{
		return IntPtr(cvGetCols(arr.ToPointer(), (CvMat*)submat.ToPointer(), start_col, end_col));
	}

	/// <summary>
	/// Select a diagonal of the input array.
	/// (diag = 0 means the main diagonal, >0 means a diagonal above the main one,
	/// <0 - below the main one).
	/// The diagonal will be represented as a column (nx1 matrix).
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="submat"></param>
	/// <param name="diag"></param>
	/// <returns></returns>
	static IntPtr GetDiag(IntPtr arr, IntPtr submat, int diag)
	{
		return IntPtr(cvGetDiag(arr.ToPointer(), (CvMat*)submat.ToPointer(), diag));
	}

	/// <summary>
	/// Select a diagonal of the input array.
	/// (diag = 0 means the main diagonal, >0 means a diagonal above the main one,
	/// <0 - below the main one).
	/// The diagonal will be represented as a column (nx1 matrix).
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="submat"></param>
	/// <returns></returns>
	static IntPtr GetDiag(IntPtr arr, IntPtr submat)
	{
		return IntPtr(cvGetDiag(arr.ToPointer(), (CvMat*)submat.ToPointer()));
	}

	/// <summary>
	/// low-level scalar <-> raw data conversion functions
	/// </summary>
	/// <param name="scalar"></param>
	/// <param name="data"></param>
	/// <param name="type"></param>
	/// <param name="extend_to_12"></param>
	static void ScalarToRawData(IntPtr scalar, IntPtr data, int type, bool extend_to_12)
	{
		cvScalarToRawData((CvScalar*)scalar.ToPointer(), data.ToPointer(), type, (int)extend_to_12);
	}

	/// <summary>
	/// low-level scalar <-> raw data conversion functions
	/// </summary>
	/// <param name="scalar"></param>
	/// <param name="data"></param>
	/// <param name="type"></param>
	static void ScalarToRawData(IntPtr scalar, IntPtr data, int type)
	{
		cvScalarToRawData((CvScalar*)scalar.ToPointer(), data.ToPointer(), type);
	}

	/// <summary>
	/// </summary>
	/// <param name="data"></param>
	/// <param name="type"></param>
	/// <param name="scalar"></param>
	static void RawDataToScalar(IntPtr data, int type, IntPtr scalar)
	{
		cvRawDataToScalar(data.ToPointer(), type, (CvScalar*)scalar.ToPointer());
	}

	/// <summary>
	/// Allocates and initializes CvMatND header
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr CreateMatNDHeader(int dims, IntPtr sizes, MatFlag type)
	{
		return IntPtr(cvCreateMatNDHeader(dims, (int*)sizes.ToPointer(), (int)type));
	}

	/// <summary>
	/// Allocates and initializes CvMatND header and allocates data
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr CreateMatND(int dims, IntPtr sizes, MatFlag type)
	{
		return IntPtr(cvCreateMatND(dims, (int*)sizes.ToPointer(), (int)type));
	}

	/// <summary>
	/// Initializes preallocated CvMatND header
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="type"></param>
	/// <param name="data"></param>
	/// <returns></returns>
	static IntPtr InitMatNDHeader(IntPtr mat, int dims, IntPtr sizes, MatFlag type, IntPtr data)
	{
		return IntPtr(cvInitMatNDHeader((CvMatND*)mat.ToPointer(), dims, (int*)sizes.ToPointer(), (int)type, data.ToPointer()));
	}

	/// <summary>
	/// Initializes preallocated CvMatND header
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr InitMatNDHeader(IntPtr mat, int dims, IntPtr sizes, MatFlag type)
	{
		return IntPtr(cvInitMatNDHeader((CvMatND*)mat.ToPointer(), dims, (int*)sizes.ToPointer(), (int)type));
	}

	/// <summary>
	/// Creates a copy of CvMatND (except, may be, steps)
	/// </summary>
	/// <param name="mat"></param>
	/// <returns></returns>
	static IntPtr CloneMatND(IntPtr mat)
	{
		return IntPtr(cvCloneMatND((CvMatND*)mat.ToPointer()));
	}

	/// <summary>
	/// Allocates and initializes CvSparseMat header and allocates data
	/// </summary>
	/// <param name="dims"></param>
	/// <param name="sizes"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr CreateSparseMat(int dims, IntPtr sizes, MatFlag type)
	{
		return IntPtr(cvCreateSparseMat(dims, (int*)sizes.ToPointer(), (int)type));
	}

	/// <summary>
	/// Releases CvSparseMat
	/// </summary>
	/// <param name="mat"></param>
	static void ReleaseSparseMat(IntPtr mat)
	{
		cvReleaseSparseMat((CvSparseMat**)mat.ToPointer());
	}

	/// <summary>
	/// Creates a copy of CvSparseMat (except, may be, zero items)
	/// </summary>
	/// <param name="mat"></param>
	/// <returns></returns>
	static IntPtr CloneSparseMat(IntPtr mat)
	{
		return IntPtr(cvCloneSparseMat((CvSparseMat*)mat.ToPointer()));
	}

	/// <summary>
	/// Initializes sparse array iterator
	/// (returns the first node or IntPtr.Zero if the array is empty)
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="mat_iterator"></param>
	/// <returns></returns>
	static IntPtr InitSparseMatIterator(IntPtr mat, IntPtr mat_iterator)
	{
		return IntPtr(cvInitSparseMatIterator((CvSparseMat*)mat.ToPointer(), (CvSparseMatIterator*)mat_iterator.ToPointer()));
	}

	/// <summary>
	/// initializes iterator that traverses through several arrays simulteneously
	/// (the function together with NextArraySlice is used for
	/// N-ari element-wise operations)
	/// </summary>
	/// <param name="count"></param>
	/// <param name="arrs"></param>
	/// <param name="mask"></param>
	/// <param name="stubs"></param>
	/// <param name="array_iterator"></param>
	/// <param name="flags"></param>
	/// <returns></returns>
	static int InitNArrayIterator(int count, IntPtr& arrs, IntPtr mask, IntPtr stubs, IntPtr array_iterator, int flags)
	{
		return cvInitNArrayIterator(count, (CvArr**)arrs.ToPointer(), mask.ToPointer(), (CvMatND*)stubs.ToPointer(), (CvNArrayIterator*)array_iterator.ToPointer(), flags);
	}

	/// <summary>
	/// initializes iterator that traverses through several arrays simulteneously
	/// (the function together with NextArraySlice is used for
	/// N-ari element-wise operations)
	/// </summary>
	/// <param name="count"></param>
	/// <param name="arrs"></param>
	/// <param name="mask"></param>
	/// <param name="stubs"></param>
	/// <param name="array_iterator"></param>
	/// <returns></returns>
	static int InitNArrayIterator(int count, IntPtr arrs, IntPtr mask, IntPtr stubs, IntPtr array_iterator)
	{
		return cvInitNArrayIterator(count, (CvArr**)arrs.ToPointer(), mask.ToPointer(), (CvMatND*)stubs.ToPointer(), (CvNArrayIterator*)array_iterator.ToPointer());
	}

	/// <summary>
	/// returns zero value if iteration is finished, non-zero (slice length) otherwise
	/// </summary>
	/// <param name="array_iterator"></param>
	/// <returns></returns>
	static int NextNArraySlice(IntPtr array_iterator)
	{
		return cvNextNArraySlice((CvNArrayIterator*)array_iterator.ToPointer());
	}

	/// <summary>
	/// Returns type of array elements:
	/// CV_8UC1 ... CV_64FC4 ...
	/// </summary>
	/// <param name="arr"></param>
	/// <returns></returns>
	static MatFlag GetElemType(IntPtr arr)
	{
		return (MatFlag)cvGetElemType(arr.ToPointer());
	}

	/// <summary>
	/// Retrieves number of an array dimensions and
	/// optionally sizes of the dimensions
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="sizes"></param>
	/// <returns></returns>
	static int GetDims(IntPtr arr, IntPtr sizes)
	{
		return cvGetDims(arr.ToPointer(), (int*)sizes.ToPointer());
	}

	/// <summary>
	/// Retrieves number of an array dimensions and
	/// optionally sizes of the dimensions
	/// </summary>
	/// <param name="arr"></param>
	/// <returns></returns>
	static int GetDims(IntPtr arr)
	{
		return cvGetDims(arr.ToPointer());
	}

	/// <summary>
	/// Retrieves size of a particular array dimension.
	/// For 2d arrays GetDimSize(arr,0) returns number of rows (image height)
	/// and GetDimSize(arr,1) returns number of columns (image width)
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="index"></param>
	/// <returns></returns>
	static int GetDimSize(IntPtr arr, int index)
	{
		return cvGetDimSize(arr.ToPointer(), index);
	}

	/// <summary>
	/// ptr = &arr(idx0,idx1,...). All indexes are zero-based,
	/// the major dimensions go first (e.g. (y,x) for 2D, (z,y,x) for 3D
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr Ptr1D(IntPtr arr, int idx0, IntPtr type)
	{
		return IntPtr(cvPtr1D(arr.ToPointer(), idx0, (int*)type.ToPointer()));
	}

	/// <summary>
	/// ptr = &arr(idx0,idx1,...). All indexes are zero-based,
	/// the major dimensions go first (e.g. (y,x) for 2D, (z,y,x) for 3D
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <returns></returns>
	static IntPtr Ptr1D(IntPtr arr, int idx0)
	{
		return IntPtr(cvPtr1D(arr.ToPointer(), idx0));
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr Ptr2D(IntPtr arr, int idx0, int idx1, IntPtr type)
	{
		return IntPtr(cvPtr2D(arr.ToPointer(), idx0, idx1, (int*)type.ToPointer()));
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <returns></returns>
	static IntPtr Ptr2D(IntPtr arr, int idx0, int idx1)
	{
		return IntPtr(cvPtr2D(arr.ToPointer(), idx0, idx1));
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="idx2"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr Ptr3D(IntPtr arr, int idx0, int idx1, int idx2, IntPtr type)
	{
		return IntPtr(cvPtr3D(arr.ToPointer(), idx0, idx1, idx2, (int*)type.ToPointer()));
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="idx2"></param>
	/// <returns></returns>
	static IntPtr Ptr3D(IntPtr arr, int idx0, int idx1, int idx2)
	{
		return IntPtr(cvPtr3D(arr.ToPointer(), idx0, idx1, idx2));
	}

	/// <summary>
	/// For CvMat or IplImage number of indices should be 2
	/// (row index (y) goes first, column index (x) goes next).
	/// For CvMatND or CvSparseMat number of infices should match number of <dims> and
	/// indices order should match the array dimension order.
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	/// <param name="type"></param>
	/// <param name="create_node"></param>
	/// <param name="precalc_hashval"></param>
	/// <returns></returns>
	static IntPtr PtrND(IntPtr arr, IntPtr idx, IntPtr type, bool create_node, IntPtr precalc_hashval)
	{
		return IntPtr(cvPtrND(arr.ToPointer(), (int*)idx.ToPointer(), (int*)type.ToPointer(), (int)create_node, (unsigned int*)precalc_hashval.ToPointer()));
	}

	/// <summary>
	/// For CvMat or IplImage number of indices should be 2
	/// (row index (y) goes first, column index (x) goes next).
	/// For CvMatND or CvSparseMat number of infices should match number of <dims> and
	/// indices order should match the array dimension order.
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	/// <param name="type"></param>
	/// <param name="create_node"></param>
	/// <returns></returns>
	static IntPtr PtrND(IntPtr arr, IntPtr idx, IntPtr type, bool create_node)
	{
		return IntPtr(cvPtrND(arr.ToPointer(), (int*)idx.ToPointer(), (int*)type.ToPointer(), (int)create_node));
	}

	/// <summary>
	/// For CvMat or IplImage number of indices should be 2
	/// (row index (y) goes first, column index (x) goes next).
	/// For CvMatND or CvSparseMat number of infices should match number of <dims> and
	/// indices order should match the array dimension order.
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	/// <param name="type"></param>
	/// <returns></returns>
	static IntPtr PtrND(IntPtr arr, IntPtr idx, IntPtr type)
	{
		return IntPtr(cvPtrND(arr.ToPointer(), (int*)idx.ToPointer(), (int*)type.ToPointer()));
	}

	/// <summary>
	/// For CvMat or IplImage number of indices should be 2
	/// (row index (y) goes first, column index (x) goes next).
	/// For CvMatND or CvSparseMat number of infices should match number of <dims> and
	/// indices order should match the array dimension order.
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	/// <returns></returns>
	static IntPtr PtrND(IntPtr arr, IntPtr idx)
	{
		return IntPtr(cvPtrND(arr.ToPointer(), (int*)idx.ToPointer()));
	}

	/// <summary>
	/// value = arr(idx0,idx1,...)
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar Get1D(IntPtr arr, int idx0)
	{
		return *(NAMESPACE::Scalar*)&cvGet1D(arr.ToPointer(), idx0);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar Get2D(IntPtr arr, int idx0, int idx1)
	{
		return *(NAMESPACE::Scalar*)&cvGet2D(arr.ToPointer(), idx0, idx1);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="idx2"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar Get3D(IntPtr arr, int idx0, int idx1, int idx2)
	{
		return *(NAMESPACE::Scalar*)&cvGet3D(arr.ToPointer(), idx0, idx1, idx2);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar GetND(IntPtr arr, IntPtr idx)
	{
		return *(NAMESPACE::Scalar*)&cvGetND(arr.ToPointer(), (int*)idx.ToPointer());
	}

	/// <summary>
	/// for 1-channel arrays
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <returns></returns>

	static double GetReal1D(IntPtr arr, int idx0)
	{
		return cvGetReal1D(arr.ToPointer(), idx0);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <returns></returns>
	static double GetReal2D(IntPtr arr, int idx0, int idx1)
	{
		return cvGetReal2D(arr.ToPointer(), idx0, idx1);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="idx2"></param>
	/// <returns></returns>
	static double GetReal3D(IntPtr arr, int idx0, int idx1, int idx2)
	{
		return cvGetReal3D(arr.ToPointer(), idx0, idx1, idx2);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	/// <returns></returns>
	static double GetRealND(IntPtr arr, IntPtr idx)
	{
		return cvGetRealND(arr.ToPointer(), (int*)idx.ToPointer());
	}

	/// <summary>
	/// arr(idx0,idx1,...) = value
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="value"></param>
	static void Set1D(IntPtr arr, int idx0, NAMESPACE::Scalar value)
	{
		cvSet1D(arr.ToPointer(), idx0, *(CvScalar*)&value);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="value"></param>
	static void Set2D(IntPtr arr, int idx0, int idx1, NAMESPACE::Scalar value)
	{
		cvSet2D(arr.ToPointer(), idx0, idx1, *(CvScalar*)&value);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="idx2"></param>
	/// <param name="value"></param>
	static void Set3D(IntPtr arr, int idx0, int idx1, int idx2, NAMESPACE::Scalar value)
	{
		cvSet3D(arr.ToPointer(), idx0, idx1, idx2, *(CvScalar*)&value);
	}


	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	/// <param name="value"></param>
	static void SetND(IntPtr arr, IntPtr idx, NAMESPACE::Scalar value)
	{
		cvSetND(arr.ToPointer(), (int*)idx.ToPointer(), *(CvScalar*)&value);
	}

	/// <summary>
	/// for 1-channel arrays
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="value"></param>
	static void SetReal1D(IntPtr arr, int idx0, double value)
	{
		cvSetReal1D(arr.ToPointer(), idx0, value);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="value"></param>

	static void SetReal2D(IntPtr arr, int idx0, int idx1, double value)
	{
		cvSetReal2D(arr.ToPointer(), idx0, idx1, value);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx0"></param>
	/// <param name="idx1"></param>
	/// <param name="idx2"></param>
	/// <param name="value"></param>
	static void SetReal3D(IntPtr arr, int idx0, int idx1, int idx2, double value)
	{
		cvSetReal3D(arr.ToPointer(), idx0, idx1, idx2, value);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	/// <param name="value"></param>
	static void SetRealND(IntPtr arr, IntPtr idx, double value)
	{
		cvSetRealND(arr.ToPointer(), (int*)idx.ToPointer(), value);
	}

	/// <summary>
	/// clears element of ND dense array,
	/// in case of sparse arrays it deletes the specified node
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="idx"></param>
	static void ClearND(IntPtr arr, IntPtr idx)
	{
		cvClearND(arr.ToPointer(), (int*)idx.ToPointer());
	}

	/// <summary>
	/// Converts CvArr (IplImage or CvMat,...) to CvMat.
	/// If the last parameter is non-zero, function can
	/// convert multi(>2)-dimensional array to CvMat as long as
	/// the last array's dimension is continous. The resultant
	/// matrix will be have appropriate (a huge) number of rows
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="header"></param>
	/// <param name="coi"></param>
	/// <param name="allowND"></param>
	/// <returns></returns>

	static IntPtr GetMat(IntPtr arr, IntPtr header, IntPtr coi, bool allowND)
	{
		return IntPtr(cvGetMat((CvMat*)arr.ToPointer(), (CvMat*)header.ToPointer(), (int*)coi.ToPointer(), (int)allowND));
	}

	/// <summary>
	/// Converts CvArr (IplImage or CvMat,...) to CvMat.
	/// If the last parameter is non-zero, function can
	/// convert multi(>2)-dimensional array to CvMat as long as
	/// the last array's dimension is continous. The resultant
	/// matrix will be have appropriate (a huge) number of rows
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="header"></param>
	/// <param name="coi"></param>
	/// <returns></returns>
	static IntPtr GetMat(IntPtr arr, IntPtr header, IntPtr coi)
	{
		return IntPtr(cvGetMat((CvMat*)arr.ToPointer(), (CvMat*)header.ToPointer(), (int*)coi.ToPointer()));
	}

	/// <summary>
	/// Converts CvArr (IplImage or CvMat,...) to CvMat.
	/// If the last parameter is non-zero, function can
	/// convert multi(>2)-dimensional array to CvMat as long as
	/// the last array's dimension is continous. The resultant
	/// matrix will be have appropriate (a huge) number of rows
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="header"></param>
	/// <returns></returns>
	static IntPtr GetMat(IntPtr arr, IntPtr header)
	{
		return IntPtr(cvGetMat((CvMat*)arr.ToPointer(), (CvMat*)header.ToPointer()));
	}

	/// <summary>
	/// Converts CvArr (IplImage or CvMat) to IplImage
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="image_header"></param>
	/// <returns></returns>
	static IntPtr GetImage(IntPtr arr, IntPtr image_header)
	{
		return IntPtr(cvGetImage(arr.ToPointer(), (IplImage*)image_header.ToPointer()));
	}

	/// <summary>
	/// Changes a shape of multi-dimensional array.
	/// new_cn == 0 means that number of channels remains unchanged.
	/// new_dims == 0 means that number and sizes of dimensions remain the same
	/// (unless they need to be changed to set the new number of channels)
	/// if new_dims == 1, there is no need to specify new dimension sizes
	/// The resultant configuration should be achievable w/o data copying.
	/// If the resultant array is sparse, SparseMat header should be passed
	/// to the function else if the result is 1 or 2 dimensional,
	/// CvMat header should be passed to the function
	/// else CvMatND header should be passed
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="sizeof_header"></param>
	/// <param name="header"></param>
	/// <param name="new_cn"></param>
	/// <param name="new_dims"></param>
	/// <param name="new_sizes"></param>
	/// <returns></returns>
	static IntPtr ReshapeMatND(IntPtr arr, int sizeof_header, IntPtr header, int new_cn, int new_dims, IntPtr new_sizes)
	{
		return IntPtr(cvReshapeMatND(arr.ToPointer(), sizeof_header, header.ToPointer(), new_cn, new_dims, (int*)new_sizes.ToPointer()));
	}

	/// <summary>
	/// Changes a shape of multi-dimensional array.
	/// new_cn == 0 means that number of channels remains unchanged.
	/// new_dims == 0 means that number and sizes of dimensions remain the same
	/// (unless they need to be changed to set the new number of channels)
	/// if new_dims == 1, there is no need to specify new dimension sizes
	/// The resultant configuration should be achievable w/o data copying.
	/// If the resultant array is sparse, SparseMat header should be passed
	/// to the function else if the result is 1 or 2 dimensional,
	/// CvMat header should be passed to the function
	/// else CvMatND header should be passed
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="header"></param>
	/// <param name="new_cn"></param>
	/// <param name="new_dims"></param>
	/// <param name="new_sizes"></param>
	/// <returns></returns>
	//static IntPtr ReshapeND<T>(IntPtr arr, IntPtr header, int new_cn, int new_dims, int[] new_sizes)
	//{
	//	return ReshapeMatND(arr, Marshal.SizeOf(typeof(T)), header, new_cn, new_dims, new_sizes);
	//}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="header"></param>
	/// <param name="new_cn"></param>
	/// <param name="new_rows"></param>
	/// <returns></returns>
	static IntPtr Reshape(IntPtr arr, IntPtr header, int new_cn, int new_rows)
	{
		return IntPtr(cvReshape(arr.ToPointer(), (CvMat*)header.ToPointer(), new_cn, new_rows));
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="header"></param>
	/// <param name="new_cn"></param>
	/// <returns></returns>
	static IntPtr Reshape(IntPtr arr, IntPtr header, int new_cn)
	{
		return IntPtr(cvReshape(arr.ToPointer(), (CvMat*)header.ToPointer(), new_cn));
	}

	/// <summary>
	/// Repeats source 2d array several times in both horizontal and
	/// vertical direction to fill destination array
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Repeat(IntPtr src, IntPtr dst)
	{
		cvRepeat(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Allocates array data
	/// </summary>
	/// <param name="arr"></param>
	static void CreateData(IntPtr arr)
	{
		cvCreateData(arr.ToPointer());
	}

	/// <summary>
	/// Releases array data
	/// </summary>
	/// <param name="arr"></param>
	static void ReleaseData(IntPtr arr)
	{
		cvReleaseData(arr.ToPointer());
	}

	/// <summary>
	/// Attaches user data to the array header. The step is reffered to
	/// the pre-last dimension. That is, all the planes of the array
	/// must be joint (w/o gaps)
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="data"></param>
	/// <param name="step"></param>
	static void SetData(IntPtr arr, IntPtr data, int step)
	{
		cvSetData(arr.ToPointer(), data.ToPointer(), step);
	}

	/// <summary>
	/// Retrieves raw data of CvMat, IplImage or CvMatND.
	/// In the latter case the function raises an error if
	/// the array can not be represented as a matrix
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="data"></param>
	/// <param name="step"></param>
	/// <param name="roi_size"></param>

	static void GetRawData(IntPtr arr, IntPtr data,IntPtr step, IntPtr roi_size)
	{
		cvGetRawData(arr.ToPointer(), (uchar**)data.ToPointer(), (int*)step.ToPointer(), (CvSize*)roi_size.ToPointer());
	}

	/// <summary>
	/// Retrieves raw data of CvMat, IplImage or CvMatND.
	/// In the latter case the function raises an error if
	/// the array can not be represented as a matrix
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="data"></param>
	/// <param name="step"></param>
	static void GetRawData(IntPtr arr, IntPtr data, IntPtr step)
	{
		cvGetRawData(arr.ToPointer(), (uchar**)data.ToPointer(), (int*)step.ToPointer());
	}

	/// <summary>
	/// Retrieves raw data of CvMat, IplImage or CvMatND.
	/// In the latter case the function raises an error if
	/// the array can not be represented as a matrix
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="data"></param>
	static void GetRawData(IntPtr arr, IntPtr data)
	{
		cvGetRawData(arr.ToPointer(), (uchar**)data.ToPointer());
	}

	/// <summary>
	/// Returns width and height of array in elements
	/// </summary>
	/// <param name="arr"></param>
	/// <returns></returns>
	static NAMESPACE::Size2D32s GetSize(IntPtr arr)
	{
		return *(NAMESPACE::Size2D32s*)&cvGetSize(arr.ToPointer());
	}

	/// <summary>
	/// Copies source array to destination array
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void Copy(IntPtr src, IntPtr dst, IntPtr mask)
	{
		cvCopy(src.ToPointer(), dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// Copies source array to destination array
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Copy(IntPtr src, IntPtr dst)
	{
		cvCopy(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Sets all or "masked" elements of input array
	/// to the same value
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="value"></param>
	/// <param name="mask"></param>
	static void Set(IntPtr arr, NAMESPACE::Scalar value, IntPtr mask)
	{
		cvSet(arr.ToPointer(), *(CvScalar*)&value, mask.ToPointer());
	}

	/// <summary>
	/// Sets all or "masked" elements of input array
	/// to the same value
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="value"></param>
	static void Set(IntPtr arr, NAMESPACE::Scalar value)
	{
		cvSet(arr.ToPointer(), *(CvScalar*)&value);
	}

	/// <summary>
	/// Clears all the array elements (sets them to 0)
	/// </summary>
	/// <param name="arr"></param>
	static void SetZero(IntPtr arr)
	{
		cvSetZero(arr.ToPointer()); 
	}

	/// <summary>
	/// Clears all the array elements (sets them to 0)
	/// </summary>
	/// <param name="arr"></param>
	static void Zero(IntPtr arr) 
	{
		cvZero(arr.ToPointer()); 
	}

	/// <summary>
	/// Splits a multi-channel array into the set of single-channel arrays or
	/// extracts particular [color] plane
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst0"></param>
	/// <param name="dst1"></param>
	/// <param name="dst2"></param>
	/// <param name="dst3"></param>
	static void Split(IntPtr src, IntPtr dst0, IntPtr dst1, IntPtr dst2, IntPtr dst3)
	{
		cvSplit(src.ToPointer(), dst0.ToPointer(), dst1.ToPointer(), dst2.ToPointer(), dst3.ToPointer());
	}

	/// <summary>
	/// Merges a set of single-channel arrays into the single multi-channel array
	/// or inserts one particular [color] plane to the array
	/// </summary>
	/// <param name="src0"></param>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="src3"></param>
	/// <param name="dst"></param>
	static void Merge(IntPtr src0, IntPtr src1, IntPtr src2, IntPtr src3, IntPtr dst)
	{
		cvMerge(src0.ToPointer(), src1.ToPointer(), src2.ToPointer(), src3.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Copies several channels from input arrays to
	/// certain channels of output arrays
	/// </summary>
	/// <param name="src"></param>
	/// <param name="src_count"></param>
	/// <param name="dst"></param>
	/// <param name="dst_count"></param>
	/// <param name="from_to"></param>
	/// <param name="pair_count"></param>
	static void MixChannels(IntPtr src, int src_count, IntPtr dst, int dst_count, IntPtr from_to, int pair_count)
	{
		return cvMixChannels((const CvArr**)src.ToPointer(), src_count, (CvArr**)dst.ToPointer(), dst_count, (int*)from_to.ToPointer(), pair_count);
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	/// <param name="shift"></param>
	static void ConvertScale(IntPtr src, IntPtr dst, double scale, double shift)
	{
		cvConvertScale(src.ToPointer(), dst.ToPointer(), scale, shift);
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	static void ConvertScale(IntPtr src, IntPtr dst, double scale)
	{
		cvConvertScale(src.ToPointer(), dst.ToPointer(), scale);
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void ConvertScale(IntPtr src, IntPtr dst)
	{
		cvConvertScale(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	/// <param name="shift"></param>
	static void CvtScale(IntPtr src, IntPtr dst, double scale, double shift)
	{
		cvCvtScale(src.ToPointer(), dst.ToPointer(), scale, shift);
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	static void CvtScale(IntPtr src, IntPtr dst, double scale)
	{
		cvCvtScale(src.ToPointer(), dst.ToPointer(), scale);
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void CvtScale(IntPtr src, IntPtr dst)
	{
		cvCvtScale(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	/// <param name="shift"></param>
	static void Scale(IntPtr src, IntPtr dst, double scale, double shift)
	{
		cvScale(src.ToPointer(), dst.ToPointer(), scale, shift);
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	static void Scale(IntPtr src, IntPtr dst, double scale)
	{
		cvScale(src.ToPointer(), dst.ToPointer(), scale);
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Scale(IntPtr src, IntPtr dst)
	{
		cvScale(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Performs linear transformation on every source array element:
	/// dst(x,y,c) = scale*src(x,y,c)+shift.
	/// Arbitrary combination of input and output array depths are allowed
	/// (number of channels must be the same), thus the function can be used
	/// for type conversion
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Convert(IntPtr src, IntPtr dst)
	{
		cvConvert(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Performs linear transformation on every source array element,
	/// stores absolute value of the result:
	/// dst(x,y,c) = abs(scale*src(x,y,c)+shift).
	/// destination array must have 8u type.
	/// In other cases one may use ConvertScale + AbsDiffS
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	/// <param name="shift"></param>
	static void ConvertScaleAbs(IntPtr src, IntPtr dst, double scale, double shift)
	{
		cvConvertScaleAbs(src.ToPointer(), dst.ToPointer(), scale, shift);
	}

	/// <summary>
	/// Performs linear transformation on every source array element,
	/// stores absolute value of the result:
	/// dst(x,y,c) = abs(scale*src(x,y,c)+shift).
	/// destination array must have 8u type.
	/// In other cases one may use ConvertScale + AbsDiffS
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	static void ConvertScaleAbs(IntPtr src, IntPtr dst, double scale)
	{
		cvConvertScaleAbs(src.ToPointer(), dst.ToPointer(), scale);
	}

	/// <summary>
	/// Performs linear transformation on every source array element,
	/// stores absolute value of the result:
	/// dst(x,y,c) = abs(scale*src(x,y,c)+shift).
	/// destination array must have 8u type.
	/// In other cases one may use ConvertScale + AbsDiffS
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void ConvertScaleAbs(IntPtr src, IntPtr dst)
	{
		cvConvertScaleAbs(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Performs linear transformation on every source array element,
	/// stores absolute value of the result:
	/// dst(x,y,c) = abs(scale*src(x,y,c)+shift).
	/// destination array must have 8u type.
	/// In other cases one may use ConvertScale + AbsDiffS
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	/// <param name="shift"></param>
	static void CvtScaleAbs(IntPtr src, IntPtr dst, double scale, double shift)
	{
		cvCvtScaleAbs(src.ToPointer(), dst.ToPointer(), scale, shift);
	}

	/// <summary>
	/// Performs linear transformation on every source array element,
	/// stores absolute value of the result:
	/// dst(x,y,c) = abs(scale*src(x,y,c)+shift).
	/// destination array must have 8u type.
	/// In other cases one may use ConvertScale + AbsDiffS
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	static void CvtScaleAbs(IntPtr src, IntPtr dst, double scale)
	{
		cvCvtScaleAbs(src.ToPointer(), dst.ToPointer(), scale);
	}

	/// <summary>
	/// Performs linear transformation on every source array element,
	/// stores absolute value of the result:
	/// dst(x,y,c) = abs(scale*src(x,y,c)+shift).
	/// destination array must have 8u type.
	/// In other cases one may use ConvertScale + AbsDiffS
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void CvtScaleAbs(IntPtr src, IntPtr dst)
	{
		cvCvtScaleAbs(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// checks termination criteria validity and
	/// sets eps to default_eps (if it is not set),
	/// max_iter to default_max_iters (if it is not set)
	/// </summary>
	/// <param name="criteria"></param>
	/// <param name="default_eps"></param>
	/// <param name="default_max_iters"></param>
	/// <returns></returns>
	static NAMESPACE::TermCriteria CheckTermCriteria(NAMESPACE::TermCriteria criteria, double default_eps, int default_max_iters)
	{
		return *(NAMESPACE::TermCriteria*)&cvCheckTermCriteria(*(CvTermCriteria*)&criteria, default_eps, default_max_iters);
	}

	/// <summary>
	/// dst(mask) = src1(mask) + src2(mask)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void Add(IntPtr src1, IntPtr src2, IntPtr dst, IntPtr mask)
	{
		cvAdd(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(mask) = src1(mask) + src2(mask)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void Add(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvAdd(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(mask) = src(mask) + value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void AddS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst, IntPtr mask)
	{
		cvAddS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(mask) = src(mask) + value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	static void AddS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst)
	{
		cvAddS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer());
	}

	/// <summary>
	/// dst(mask) = src1(mask) - src2(mask)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void Sub(IntPtr src1, IntPtr src2, IntPtr dst, IntPtr mask)
	{
		cvSub(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(mask) = src1(mask) - src2(mask)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void Sub(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvSub(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(mask) = value - src(mask)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void SubRS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst, IntPtr mask)
	{
		cvSubRS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(mask) = value - src(mask)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	static void SubRS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst)
	{
		cvSubRS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src1(idx) * src2(idx) * scale
	/// (scaled element-wise multiplication of 2 arrays)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	static void Mul(IntPtr src1, IntPtr src2, IntPtr dst, double scale)
	{
		cvMul(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), scale);
	}

	/// <summary>
	/// dst(idx) = src1(idx) * src2(idx) * scale
	/// (scaled element-wise multiplication of 2 arrays)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void Mul(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvMul(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// element-wise division/inversion with scaling:
	/// dst(idx) = src1(idx) * scale / src2(idx)
	/// or dst(idx) = scale / src2(idx) if src1 == 0
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="scale"></param>
	static void Div(IntPtr src1, IntPtr src2, IntPtr dst, double scale)
	{
		cvDiv(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), scale);
	}

	/// <summary>
	/// element-wise division/inversion with scaling:
	/// dst(idx) = src1(idx) * scale / src2(idx)
	/// or dst(idx) = scale / src2(idx) if src1 == 0
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void Div(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvDiv(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst = src1 * scale + src2
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="scale"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void ScaleAdd(IntPtr src1, NAMESPACE::Scalar scale, IntPtr src2, IntPtr dst)
	{
		cvScaleAdd(src1.ToPointer(), *(CvScalar*)&scale, src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst = src1 * scale + src2
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="scale"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void AXPY(IntPtr src1, double real_scalar, IntPtr src2, IntPtr dst)
	{
		cvAXPY(src1.ToPointer(), real_scalar, src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst = src1 * alpha + src2 * beta + gamma
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="alpha"></param>
	/// <param name="src2"></param>
	/// <param name="beta"></param>
	/// <param name="gamma"></param>
	/// <param name="dst"></param>
	static void AddWeighted(IntPtr src1, double alpha, IntPtr src2, double beta, double gamma, IntPtr dst)
	{
		cvAddWeighted(src1.ToPointer(), alpha, src2.ToPointer(), beta, gamma, dst.ToPointer());
	}

	/// <summary>
	/// result = sum_i(src1(i) * src2(i)) (results for all channels are accumulated together)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <returns></returns>
	static double DotProduct(IntPtr src1, IntPtr src2)
	{
		return cvDotProduct(src1.ToPointer(), src2.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src1(idx) & src2(idx)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void And(IntPtr src1, IntPtr src2, IntPtr dst, IntPtr mask)
	{
		cvAnd(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src1(idx) & src2(idx)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void And(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvAnd(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src(idx) & value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void AndS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst, IntPtr mask)
	{
		cvAndS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src(idx) & value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	static void AndS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst)
	{
		cvAndS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src1(idx) | src2(idx)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void Or(IntPtr src1, IntPtr src2, IntPtr dst, IntPtr mask)
	{
		cvOr(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src1(idx) | src2(idx)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void Or(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvOr(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src(idx) | value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void OrS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst, IntPtr mask)
	{
		cvOrS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src(idx) | value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	static void OrS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst)
	{
		cvOrS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src1(idx) ^ src2(idx)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void Xor(IntPtr src1, IntPtr src2, IntPtr dst, IntPtr mask)
	{
		cvXor(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src1(idx) ^ src2(idx)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void Xor(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvXor(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src(idx) ^ value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	/// <param name="mask"></param>
	static void XorS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst, IntPtr mask)
	{
		cvXorS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src(idx) ^ value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	static void XorS(IntPtr src, NAMESPACE::Scalar value, IntPtr dst)
	{
		cvXorS(src.ToPointer(), *(CvScalar*)&value, dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = ~src(idx)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Not(IntPtr src, IntPtr dst)
	{
		cvNot(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = lower(idx) <= src(idx) < upper(idx)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="lower"></param>
	/// <param name="upper"></param>
	/// <param name="dst"></param>
	static void InRange(IntPtr src, IntPtr lower, IntPtr upper, IntPtr dst)
	{
		cvInRange(src.ToPointer(), lower.ToPointer(), upper.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = lower <= src(idx) < upper
	/// </summary>
	/// <param name="src"></param>
	/// <param name="lower"></param>
	/// <param name="upper"></param>
	/// <param name="dst"></param>
	static void InRangeS(IntPtr src, NAMESPACE::Scalar lower, NAMESPACE::Scalar upper, IntPtr dst)
	{
		cvInRangeS(src.ToPointer(), *(CvScalar*)&lower, *(CvScalar*)&upper, dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = src1(idx) _cmp_op_ src2(idx)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="cmp_op"></param>
	static void Cmp(IntPtr src1, IntPtr src2, IntPtr dst, ArrCmpOption cmp_op)
	{
		cvCmp(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), (int)cmp_op);
	}

	/// <summary>
	/// dst(idx) = src1(idx) _cmp_op_ value
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	/// <param name="cmp_op"></param>
	static void CmpS(IntPtr src, double value, IntPtr dst, ArrCmpOption cmp_op)
	{
		cvCmpS(src.ToPointer(), value, dst.ToPointer(), (int)cmp_op);
	}

	/// <summary>
	/// dst(idx) = min(src1(idx),src2(idx))
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void Min(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvMin(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = max(src1(idx),src2(idx))
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void Max(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvMax(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = min(src(idx),value)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	static void MinS(IntPtr src, double value, IntPtr dst)
	{
		cvMinS(src.ToPointer(), value, dst.ToPointer());
	}

	/// <summary>
	/// dst(idx) = max(src(idx),value)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="value"></param>
	/// <param name="dst"></param>
	static void MaxS(IntPtr src, double value, IntPtr dst)
	{
		cvMaxS(src.ToPointer(), value, dst.ToPointer());
	}

	/// <summary>
	/// dst(x,y,c) = abs(src1(x,y,c) - src2(x,y,c))
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void AbsDiff(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvAbsDiff(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// dst(x,y,c) = abs(src(x,y,c) - value(c))
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="value"></param>
	static void AbsDiffS(IntPtr src, IntPtr dst, NAMESPACE::Scalar value)
	{
		cvAbsDiffS(src.ToPointer(), dst.ToPointer(), *(CvScalar*)&value);
	}

	/// <summary>
	/// dst(x,y,c) = abs(src(x,y,c) - value(c))
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="value"></param>
	static void Abs(IntPtr src, IntPtr dst)
	{
		cvAbs(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Does cartesian->polar coordinates conversion.
	/// Either of output components (magnitude or angle) is optional
	/// </summary>
	/// <param name="x"></param>
	/// <param name="y"></param>
	/// <param name="magnitude"></param>
	/// <param name="angle"></param>
	/// <param name="angle_in_degrees"></param>
	static void CartToPolar(IntPtr x, IntPtr y, IntPtr magnitude, IntPtr angle, bool angle_in_degrees)
	{
		cvCartToPolar(x.ToPointer(), y.ToPointer(), magnitude.ToPointer(), angle.ToPointer(), (int)angle_in_degrees);
	}

	/// <summary>
	/// Does cartesian->polar coordinates conversion.
	/// Either of output components (magnitude or angle) is optional
	/// </summary>
	/// <param name="x"></param>
	/// <param name="y"></param>
	/// <param name="magnitude"></param>
	/// <param name="angle"></param>
	static void CartToPolar(IntPtr x, IntPtr y, IntPtr magnitude, IntPtr angle)
	{
		cvCartToPolar(x.ToPointer(), y.ToPointer(), magnitude.ToPointer(), angle.ToPointer());
	}

	/// <summary>
	/// Does cartesian->polar coordinates conversion.
	/// Either of output components (magnitude or angle) is optional
	/// </summary>
	/// <param name="x"></param>
	/// <param name="y"></param>
	/// <param name="magnitude"></param>
	static void CartToPolar(IntPtr x, IntPtr y, IntPtr magnitude)
	{
		cvCartToPolar(x.ToPointer(), y.ToPointer(), magnitude.ToPointer());
	}

	/// <summary>
	/// Does polar->cartesian coordinates conversion.
	/// Either of output components (magnitude or angle) is optional.
	/// If magnitude is missing it is assumed to be all 1's
	/// </summary>
	/// <param name="magnitude"></param>
	/// <param name="angle"></param>
	/// <param name="x"></param>
	/// <param name="y"></param>
	/// <param name="angle_in_degrees"></param>
	static void PolarToCart(IntPtr magnitude, IntPtr angle, IntPtr x, IntPtr y, bool angle_in_degrees)
	{
		cvPolarToCart(magnitude.ToPointer(), angle.ToPointer(), x.ToPointer(), y.ToPointer(), (int)angle_in_degrees);
	}

	/// <summary>
	/// Does polar->cartesian coordinates conversion.
	/// Either of output components (magnitude or angle) is optional.
	/// If magnitude is missing it is assumed to be all 1's
	/// </summary>
	/// <param name="magnitude"></param>
	/// <param name="angle"></param>
	/// <param name="x"></param>
	/// <param name="y"></param>
	static void PolarToCart(IntPtr magnitude, IntPtr angle, IntPtr x, IntPtr y)
	{
		cvPolarToCart(magnitude.ToPointer(), angle.ToPointer(), x.ToPointer(), y.ToPointer());
	}

	/// <summary>
	/// Does powering: dst(idx) = src(idx)^power
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="power"></param>
	static void Pow(IntPtr src, IntPtr dst, double power)
	{
		cvPow(src.ToPointer(), dst.ToPointer(), power);
	}

	/// <summary>
	/// Does exponention: dst(idx) = exp(src(idx)).
	/// Overflow is not handled yet. Underflow is handled.
	/// Maximal relative error is ~7e-6 for single-precision input
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Exp(IntPtr src, IntPtr dst)
	{
		cvExp(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Calculates natural logarithms: dst(idx) = log(abs(src(idx))).
	/// Logarithm of 0 gives large negative number(~-700)
	/// Maximal relative error is ~3e-7 for single-precision output
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Log(IntPtr src, IntPtr dst)
	{
		cvLog(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Fast arctangent calculation
	/// </summary>
	/// <param name="y"></param>
	/// <param name="x"></param>
	/// <returns></returns>
	static float FastArctan(float y, float x)
	{
		return cvFastArctan(y, x);
	}

	/// <summary>
	/// Fast cubic root calculation
	/// </summary>
	/// <param name="value"></param>
	/// <returns></returns>
	static float Cbrt(float value)
	{
		return cvCbrt(value);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="flags"></param>
	/// <param name="min_val"></param>
	/// <param name="max_val"></param>
	/// <returns></returns>
	static int CheckArr(IntPtr arr, CheckArrFlag flags, double min_val, double max_val)
	{
		return cvCheckArr(arr.ToPointer(), (int)flags, min_val, max_val);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="flags"></param>
	/// <param name="min_val"></param>
	/// <returns></returns>
	static int CheckArr(IntPtr arr, CheckArrFlag flags, double min_val)
	{
		return cvCheckArr(arr.ToPointer(), (int)flags, min_val);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="flags"></param>
	/// <returns></returns>
	static int CheckArr(IntPtr arr, CheckArrFlag flags)
	{
		return cvCheckArr(arr.ToPointer(), (int)flags);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <returns></returns>
	static int CheckArr(IntPtr arr)
	{
		return cvCheckArr(arr.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="flags"></param>
	/// <param name="min_val"></param>
	/// <param name="max_val"></param>
	/// <returns></returns>
	static int CheckArray(IntPtr arr, CheckArrFlag flags, double min_val, double max_val)
	{
		return cvCheckArray(arr.ToPointer(), (int)flags, min_val, max_val);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="flags"></param>
	/// <param name="min_val"></param>
	/// <returns></returns>
	static int CheckArray(IntPtr arr, CheckArrFlag flags, double min_val)
	{
		return cvCheckArray(arr.ToPointer(), (int)flags, min_val);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="flags"></param>
	/// <returns></returns>
	static int CheckArray(IntPtr arr, CheckArrFlag flags)
	{
		return cvCheckArray(arr.ToPointer(), (int)flags);
	}

	/// <summary>
	/// </summary>
	/// <param name="arr"></param>
	/// <returns></returns>
	static int CheckArray(IntPtr arr)
	{
		return cvCheckArray(arr.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="rng"></param>
	/// <param name="arr"></param>
	/// <param name="dist_type"></param>
	/// <param name="param1"></param>
	/// <param name="param2"></param>
	static void RandArr(IntPtr rng, IntPtr arr, int dist_type, NAMESPACE::Scalar param1, NAMESPACE::Scalar param2)
	{
		cvRandArr((CvRNG*)rng.ToPointer(), arr.ToPointer(), dist_type, *(CvScalar*)(&param1), *(CvScalar*)(&param2));
	}

	/// <summary>
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="rng"></param>
	/// <param name="iter_factor"></param>
	static void RandShuffle(IntPtr mat, IntPtr rng, double iter_factor)
	{
		cvRandShuffle(mat.ToPointer(), (CvRNG*)rng.ToPointer(), iter_factor);
	}

	/// <summary>
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="rng"></param>
	static void RandShuffle(IntPtr mat, IntPtr rng)
	{
		cvRandShuffle(mat.ToPointer(), (CvRNG*)rng.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="idxmat"></param>
	/// <param name="flags"></param>
	static void Sort(IntPtr src, IntPtr dst, IntPtr idxmat, SortFlag flags)
	{
		cvSort(src.ToPointer(), dst.ToPointer(), idxmat.ToPointer(), (int)flags);
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="idxmat"></param>
	static void Sort(IntPtr src, IntPtr dst, IntPtr idxmat)
	{
		cvSort(src.ToPointer(), dst.ToPointer(), idxmat.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Sort(IntPtr src, IntPtr dst)
	{
		cvSort(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	static void Sort(IntPtr src)
	{
		cvSort(src.ToPointer());
	}

	/// <summary>
	/// Finds real roots of a cubic equation
	/// </summary>
	/// <param name="coeffs"></param>
	/// <param name="roots"></param>
	/// <returns></returns>
	static int SolveCubic(IntPtr coeffs, IntPtr roots)
	{
		return cvSolveCubic((CvMat*)coeffs.ToPointer(), (CvMat*)roots.ToPointer());
	}

	/// <summary>
	/// Finds all real and complex roots of a polynomial equation
	/// </summary>
	/// <param name="coeffs"></param>
	/// <param name="roots2"></param>
	/// <param name="maxiter"></param>
	/// <param name="fig"></param>
	static void SolvePoly(IntPtr coeffs, IntPtr roots2, int maxiter, int fig)
	{
		cvSolvePoly((CvMat*)coeffs.ToPointer(), (CvMat*)roots2.ToPointer(), maxiter, fig);
	}

	/// <summary>
	/// Finds all real and complex roots of a polynomial equation
	/// </summary>
	/// <param name="coeffs"></param>
	/// <param name="roots2"></param>
	/// <param name="maxiter"></param>
	static void SolvePoly(IntPtr coeffs, IntPtr roots2, int maxiter)
	{
		cvSolvePoly((CvMat*)coeffs.ToPointer(), (CvMat*)roots2.ToPointer(), maxiter);
	}

	/// <summary>
	/// Finds all real and complex roots of a polynomial equation
	/// </summary>
	/// <param name="coeffs"></param>
	/// <param name="roots2"></param>
	static void SolvePoly(IntPtr coeffs, IntPtr roots2)
	{
		cvSolvePoly((CvMat*)coeffs.ToPointer(), (CvMat*)roots2.ToPointer());
	}

	/// <summary>
	/// Calculates cross product of two 3d vectors
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void CrossProduct(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvCrossProduct(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Extended matrix transform:
	/// dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="alpha"></param>
	/// <param name="src3"></param>
	/// <param name="beta"></param>
	/// <param name="dst"></param>
	/// <param name="tABC"></param>
	static void GEMM(IntPtr src1, IntPtr src2, double alpha, IntPtr src3, double beta, IntPtr dst, GEMMOpFlag tABC)
	{
		cvGEMM((src1.ToPointer()), (src2.ToPointer()), alpha, src3.ToPointer(), beta, dst.ToPointer(), (int)tABC);
	}

	/// <summary>
	/// Extended matrix transform:
	/// dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="alpha"></param>
	/// <param name="src3"></param>
	/// <param name="beta"></param>
	/// <param name="dst"></param>
	static void GEMM(IntPtr src1, IntPtr src2, double alpha, IntPtr src3, double beta, IntPtr dst)
	{
		cvGEMM(src1.ToPointer(), src2.ToPointer(), alpha, src3.ToPointer(), beta, dst.ToPointer());
	}

	/// <summary>
	/// Extended matrix transform:
	/// dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="alpha"></param>
	/// <param name="src3"></param>
	/// <param name="beta"></param>
	/// <param name="dst"></param>
	/// <param name="tABC"></param>
	static void MatMulAddEx(IntPtr src1, IntPtr src2, double alpha, IntPtr src3, double beta, IntPtr dst, GEMMOpFlag tABC)
	{
		cvMatMulAddEx((src1.ToPointer()), (src2.ToPointer()), alpha, src3.ToPointer(), beta, dst.ToPointer(), (int)tABC);
	}

	/// <summary>
	/// Extended matrix transform:
	/// dst = alpha*op(A)*op(B) + beta*op(C), where op(X) is X or X^T
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="alpha"></param>
	/// <param name="src3"></param>
	/// <param name="beta"></param>
	/// <param name="dst"></param>
	static void MatMulAddEx(IntPtr src1, IntPtr src2, double alpha, IntPtr src3, double beta, IntPtr dst)
	{
		cvMatMulAddEx((src1.ToPointer()), (src2.ToPointer()), alpha, src3.ToPointer(), beta, dst.ToPointer());
	}

	/// <summary>
	/// Matrix transform: dst = A*B + C, C is optional
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="src3"></param>
	/// <param name="dst"></param>
	static void MatMulAdd(IntPtr src1, IntPtr src2, IntPtr src3, IntPtr dst)
	{
		cvMatMulAdd((src1.ToPointer()), (src2.ToPointer()), src3.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// MatMul
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	static void MatMul(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		cvMatMul((src1.ToPointer()), (src2.ToPointer()), (dst.ToPointer()));
	}

	/// <summary>
	/// Transforms each element of source array and stores
	/// resultant vectors in destination array
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="transmat"></param>
	/// <param name="shiftvec"></param>
	static void Transform(IntPtr src, IntPtr dst, IntPtr transmat, IntPtr shiftvec)
	{
		cvTransform(src.ToPointer(), dst.ToPointer(), (CvMat*)transmat.ToPointer(), (CvMat*)shiftvec.ToPointer());
	}

	/// <summary>
	/// Transforms each element of source array and stores
	/// resultant vectors in destination array
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="transmat"></param>
	static void Transform(IntPtr src, IntPtr dst, IntPtr transmat)
	{
		cvTransform(src.ToPointer(), dst.ToPointer(), (CvMat*)transmat.ToPointer());
	}

	/// <summary>
	/// Transforms each element of source array and stores
	/// resultant vectors in destination array
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="transmat"></param>
	/// <param name="shiftvec"></param>
	static void MatMulAddS(IntPtr src, IntPtr dst, IntPtr transmat, IntPtr shiftvec)
	{
		cvMatMulAddS(src.ToPointer(), dst.ToPointer(), (CvMat*)transmat.ToPointer(), (CvMat*)shiftvec.ToPointer());
	}

	/// <summary>
	/// Transforms each element of source array and stores
	/// resultant vectors in destination array
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="transmat"></param>
	static void MatMulAddS(IntPtr src, IntPtr dst, IntPtr transmat)
	{
		cvMatMulAddS(src.ToPointer(), dst.ToPointer(), (CvMat*)transmat.ToPointer());
	}

	/// <summary>
	/// Does perspective transform on every element of input array
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="mat"></param>
	static void PerspectiveTransform(IntPtr src, IntPtr dst, IntPtr mat)
	{
		cvPerspectiveTransform(src.ToPointer(), dst.ToPointer(), (CvMat*)mat.ToPointer());
	}

	/// <summary>
	/// Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="order"></param>
	/// <param name="delta"></param>
	/// <param name="scale"></param>
	static void MulTransposed(IntPtr src, IntPtr dst, MulTransOrder order, IntPtr delta, double scale)
	{
		cvMulTransposed(src.ToPointer(), dst.ToPointer(), (int)order, delta.ToPointer(), scale);
	}

	/// <summary>
	/// Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="order"></param>
	/// <param name="delta"></param>
	static void MulTransposed(IntPtr src, IntPtr dst, MulTransOrder order, IntPtr delta)
	{
		cvMulTransposed(src.ToPointer(), dst.ToPointer(), (int)order, delta.ToPointer());
	}

	/// <summary>
	/// Calculates (A-delta)*(A-delta)^T (order=0) or (A-delta)^T*(A-delta) (order=1)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="order"></param>
	static void MulTransposed(IntPtr src, IntPtr dst, MulTransOrder order)
	{
		cvMulTransposed(src.ToPointer(), dst.ToPointer(), (int)order);
	}

	/// <summary>
	/// Tranposes matrix. Square matrices can be transposed in-place
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Transpose(IntPtr src, IntPtr dst)	
	{
		cvTranspose(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Tranposes matrix. Square matrices can be transposed in-place
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void T(IntPtr src, IntPtr dst)
	{
		cvT(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part
	/// </summary>
	/// <param name="matrix"></param>
	/// <param name="LtoR"></param>
	static void CompleteSymm(IntPtr matrix, CompleteSymmOp LtoR)
	{
		cvCompleteSymm((CvMat*)matrix.ToPointer(), (int)LtoR);
	}

	/// <summary>
	/// Completes the symmetric matrix from the lower (LtoR=0) or from the upper (LtoR!=0) part
	/// </summary>
	/// <param name="matrix"></param>
	static void CompleteSymm(IntPtr matrix)
	{
		cvCompleteSymm((CvMat*)matrix.ToPointer());
	}

	/// <summary>
	/// Mirror array data around horizontal (flip=0),
	/// vertical (flip=1) or both(flip=-1) axises:
	/// Flip(src) flips images vertically and sequences horizontally (inplace)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="flip_mode"></param>
	static void Flip(IntPtr src, IntPtr dst, FlipMode flip_mode)
	{
		cvFlip(src.ToPointer(), dst.ToPointer(), (int)flip_mode);
	}

	/// <summary>
	/// Mirror array data around horizontal (flip=0),
	/// vertical (flip=1) or both(flip=-1) axises:
	/// Flip(src) flips images vertically and sequences horizontally (inplace)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Flip(IntPtr src, IntPtr dst)
	{
		cvFlip(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Mirror array data around horizontal (flip=0),
	/// vertical (flip=1) or both(flip=-1) axises:
	/// Flip(src) flips images vertically and sequences horizontally (inplace)
	/// </summary>
	/// <param name="src"></param>
	static void Flip(IntPtr src)
	{
		cvFlip(src.ToPointer());
	}

	/// <summary>
	/// Mirror array data around horizontal (flip=0),
	/// vertical (flip=1) or both(flip=-1) axises:
	/// Flip(src) flips images vertically and sequences horizontally (inplace)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="flip_mode"></param>
	static void Mirror(IntPtr src, IntPtr dst, FlipMode flip_mode)
	{
		cvMirror(src.ToPointer(), dst.ToPointer(), (int)flip_mode);
	}

	/// <summary>
	/// Mirror array data around horizontal (flip=0),
	/// vertical (flip=1) or both(flip=-1) axises:
	/// Flip(src) flips images vertically and sequences horizontally (inplace)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Mirror(IntPtr src, IntPtr dst)
	{
		cvMirror(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Mirror array data around horizontal (flip=0),
	/// vertical (flip=1) or both(flip=-1) axises:
	/// Flip(src) flips images vertically and sequences horizontally (inplace)
	/// </summary>
	/// <param name="src"></param>
	static void Mirror(IntPtr src)
	{
		cvMirror(src.ToPointer());
	}

	/// <summary>
	/// Performs Singular Value Decomposition of a matrix
	/// </summary>
	/// <param name="A"></param>
	/// <param name="W"></param>
	/// <param name="U"></param>
	/// <param name="V"></param>
	/// <param name="flags"></param>
	static void SVD(IntPtr A, IntPtr W, IntPtr U, IntPtr V, SVDFlag flags)
	{
		cvSVD(A.ToPointer(), W.ToPointer(), U.ToPointer(), V.ToPointer(), (int)flags);
	}

	/// <summary>
	/// Performs Singular Value Decomposition of a matrix
	/// </summary>
	/// <param name="A"></param>
	/// <param name="W"></param>
	/// <param name="U"></param>
	/// <param name="V"></param>
	static void SVD(IntPtr A, IntPtr W, IntPtr U, IntPtr V)
	{
		cvSVD(A.ToPointer(), W.ToPointer(), U.ToPointer(), V.ToPointer());
	}

	/// <summary>
	/// Performs Singular Value Decomposition of a matrix
	/// </summary>
	/// <param name="A"></param>
	/// <param name="W"></param>
	/// <param name="U"></param>
	static void SVD(IntPtr A, IntPtr W, IntPtr U)
	{
		cvSVD(A.ToPointer(), W.ToPointer(), U.ToPointer());
	}

	/// <summary>
	/// Performs Singular Value Decomposition of a matrix
	/// </summary>
	/// <param name="A"></param>
	/// <param name="W"></param>
	static void SVD(IntPtr A, IntPtr W)
	{
		cvSVD(A.ToPointer(), W.ToPointer());
	}

	/// <summary>
	/// Performs Singular Value Back Substitution (solves A*X = B):
	/// flags must be the same as in SVD
	/// </summary>
	/// <param name="W"></param>
	/// <param name="U"></param>
	/// <param name="V"></param>
	/// <param name="B"></param>
	/// <param name="X"></param>
	/// <param name="flags"></param>
	static void SVBkSb(IntPtr W, IntPtr U, IntPtr V, IntPtr B, IntPtr X, SVDFlag flags)
	{
		cvSVBkSb(W.ToPointer(), U.ToPointer(), V.ToPointer(), B.ToPointer(), X.ToPointer(), (int)flags);
	}

	/// <summary>
	/// Inverts matrix
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static double Invert(IntPtr src, IntPtr dst, MatrixMethod method)
	{
		return cvInvert(src.ToPointer(), dst.ToPointer(), (int)method);
	}

	/// <summary>
	/// Inverts matrix
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <returns></returns>
	static double Invert(IntPtr src, IntPtr dst)
	{
		return cvInvert(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Inverts matrix
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static double Inv(IntPtr src, IntPtr dst, MatrixMethod method)
	{
		return cvInv(src.ToPointer(), dst.ToPointer(), (int)method);
	}

	/// <summary>
	/// Inverts matrix
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <returns></returns>
	static double Inv(IntPtr src, IntPtr dst)
	{
		return cvInv(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Solves linear system (src1)*(dst) = (src2)
	/// (returns 0 if src1 is a singular and CV_LU method is used)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="method"></param>
	/// <returns></returns>
	static int Solve(IntPtr src1, IntPtr src2, IntPtr dst, MatrixMethod method)
	{
		return cvSolve(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), (int)method);
	}

	/// <summary>
	/// Solves linear system (src1)*(dst) = (src2)
	/// (returns 0 if src1 is a singular and CV_LU method is used)
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <returns></returns>
	static int Solve(IntPtr src1, IntPtr src2, IntPtr dst)
	{
		return cvSolve(src1.ToPointer(), src2.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Calculates determinant of input matrix
	/// </summary>
	/// <param name="mat"></param>
	/// <returns></returns>
	static double Det(IntPtr mat)
	{
		return cvDet(mat.ToPointer());
	}

	/// <summary>
	/// Calculates trace of the matrix (sum of elements on the main diagonal)
	/// </summary>
	/// <param name="mat"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar Trace(IntPtr mat)
	{
		CvScalar scale = cvTrace(mat.ToPointer());
		return NAMESPACE::Scalar(scale.val[0], scale.val[1], scale.val[2], scale.val[3]);
	}

	/// <summary>
	/// Finds eigen values and vectors of a symmetric matrix
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="evects"></param>
	/// <param name="evals"></param>
	/// <param name="eps"></param>
	/// <param name="lowindex"></param>
	/// <param name="highindex"></param>
	static void EigenVV(IntPtr mat, IntPtr evects, IntPtr evals, double eps, int lowindex, int highindex)
	{
		cvEigenVV(mat.ToPointer(), evects.ToPointer(), evals.ToPointer(), eps, lowindex, highindex);
	}

	/// <summary>
	/// Finds eigen values and vectors of a symmetric matrix
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="evects"></param>
	/// <param name="evals"></param>
	/// <param name="eps"></param>
	/// <param name="lowindex"></param>
	static void EigenVV(IntPtr mat, IntPtr evects, IntPtr evals, double eps, int lowindex)
	{
		cvEigenVV(mat.ToPointer(), evects.ToPointer(), evals.ToPointer(), eps, lowindex);
	}

	/// <summary>
	/// Finds eigen values and vectors of a symmetric matrix
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="evects"></param>
	/// <param name="evals"></param>
	/// <param name="eps"></param>
	static void EigenVV(IntPtr mat, IntPtr evects, IntPtr evals, double eps)
	{
		cvEigenVV(mat.ToPointer(), evects.ToPointer(), evals.ToPointer(), eps);
	}

	/// <summary>
	/// Finds eigen values and vectors of a symmetric matrix
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="evects"></param>
	/// <param name="evals"></param>
	static void EigenVV(IntPtr mat, IntPtr evects, IntPtr evals)
	{
		cvEigenVV(mat.ToPointer(), evects.ToPointer(), evals.ToPointer());
	}

	/// <summary>
	/// Makes an identity matrix (mat_ij = i == j)
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="value"></param>
	static void SetIdentity(IntPtr mat, NAMESPACE::Scalar value)
	{
		cvSetIdentity(mat.ToPointer(), *(CvScalar*)&value);
	}

	/// <summary>
	/// Makes an identity matrix (mat_ij = i == j)
	/// </summary>
	/// <param name="mat"></param>
	static void SetIdentity(IntPtr mat)
	{
		cvSetIdentity(mat.ToPointer());
	}

	/// <summary>
	/// Fills matrix with given range of numbers
	/// </summary>
	/// <param name="mat"></param>
	/// <param name="start"></param>
	/// <param name="end"></param>
	/// <returns></returns>
	static IntPtr Range(IntPtr mat, double start, double end)
	{
		return IntPtr(cvRange(mat.ToPointer(), start, end));
	}

	/// <summary>
	/// </summary>
	/// <param name="vects"></param>
	/// <param name="count"></param>
	/// <param name="cov_mat"></param>
	/// <param name="avg"></param>
	/// <param name="flags"></param>
	static void CalcCovarMatrix(IntPtr vects, int count, IntPtr cov_mat, IntPtr avg, CovarFlag flags)
	{
		cvCalcCovarMatrix((const CvArr**)vects.ToPointer(), count, cov_mat.ToPointer(), avg.ToPointer(), (int)flags);
	}

	/// <summary>
	/// </summary>
	/// <param name="data"></param>
	/// <param name="mean"></param>
	/// <param name="eigenvals"></param>
	/// <param name="eigenvects"></param>
	/// <param name="flags"></param>
	static void CalcPCA(IntPtr data, IntPtr mean, IntPtr eigenvals, IntPtr eigenvects, CalPCAFlag flags)
	{
		cvCalcPCA(data.ToPointer(), mean.ToPointer(), eigenvals.ToPointer(), eigenvects.ToPointer(), (int)flags);
	}

	/// <summary>
	/// </summary>
	/// <param name="data"></param>
	/// <param name="mean"></param>
	/// <param name="eigenvects"></param>
	/// <param name="result"></param>
	static void ProjectPCA(IntPtr data, IntPtr mean, IntPtr eigenvects, IntPtr result)
	{
		cvProjectPCA(data.ToPointer(), mean.ToPointer(), eigenvects.ToPointer(), result.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="proj"></param>
	/// <param name="mean"></param>
	/// <param name="eigenvects"></param>
	/// <param name="result"></param>
	static void BackProjectPCA(IntPtr proj, IntPtr mean, IntPtr eigenvects, IntPtr result)
	{
		cvBackProjectPCA(proj.ToPointer(), mean.ToPointer(), eigenvects.ToPointer(), result.ToPointer());
	}

	/// <summary>
	/// Calculates Mahalanobis(weighted) distance
	/// </summary>
	/// <param name="vec1"></param>
	/// <param name="vec2"></param>
	/// <param name="mat"></param>
	/// <returns></returns>
	static double Mahalanobis(IntPtr vec1, IntPtr vec2, IntPtr mat)
	{
		return cvMahalanobis(vec1.ToPointer(), vec2.ToPointer(), mat.ToPointer());
	}

	/// <summary>
	/// Calculates Mahalonobis(weighted) distance
	/// </summary>
	/// <param name="vec1"></param>
	/// <param name="vec2"></param>
	/// <param name="mat"></param>
	/// <returns></returns>
	static double Mahalonobis(IntPtr vec1, IntPtr vec2, IntPtr mat)
	{
		return cvMahalanobis(vec1.ToPointer(), vec2.ToPointer(), mat.ToPointer());
	}

	/// <summary>
	/// Finds sum of array elements
	/// </summary>
	/// <param name="arr"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar Sum(IntPtr arr)
	{
		CvScalar scale = cvSum(arr.ToPointer());
		return NAMESPACE::Scalar(scale.val[0], scale.val[1], scale.val[2], scale.val[3]);
	}

	/// <summary>
	/// Calculates number of non-zero pixels
	/// </summary>
	/// <param name="arr"></param>
	/// <returns></returns>
	static int CountNonZero(IntPtr arr)
	{
		return cvCountNonZero(arr.ToPointer());
	}

	/// <summary>
	/// Calculates mean value of array elements
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="mask"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar Avg(IntPtr arr, IntPtr mask)
	{
		CvScalar scale = cvAvg(arr.ToPointer(), mask.ToPointer());
		return NAMESPACE::Scalar(scale.val[0], scale.val[1], scale.val[2], scale.val[3]);
	}

	/// <summary>
	/// Calculates mean value of array elements
	/// </summary>
	/// <param name="arr"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar Avg(IntPtr arr)
	{
		CvScalar scale = cvAvg(arr.ToPointer());
		return NAMESPACE::Scalar(scale.val[0], scale.val[1], scale.val[2], scale.val[3]);
	}

	/// <summary>
	/// Calculates mean and standard deviation of pixel values
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="mean"></param>
	/// <param name="std_dev"></param>
	/// <param name="mask"></param>
	static void AvgSdv(IntPtr arr, IntPtr mean, IntPtr std_dev, IntPtr mask)
	{
		cvAvgSdv(arr.ToPointer(), (CvScalar*)mean.ToPointer(), (CvScalar*)std_dev.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// Calculates mean and standard deviation of pixel values
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="mean"></param>
	/// <param name="std_dev"></param>
	static void AvgSdv(IntPtr arr, IntPtr mean, IntPtr std_dev)
	{
		cvAvgSdv(arr.ToPointer(), (CvScalar*)mean.ToPointer(), (CvScalar*)std_dev.ToPointer());
	}

	/// <summary>
	/// Finds global minimum, maximum and their positions
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="min_val"></param>
	/// <param name="max_val"></param>
	/// <param name="min_loc"></param>
	/// <param name="max_loc"></param>
	/// <param name="mask"></param>
	static void MinMaxLoc(IntPtr arr, IntPtr min_val, IntPtr max_val, IntPtr min_loc, IntPtr max_loc, IntPtr mask)
	{
		cvMinMaxLoc(arr.ToPointer(), (double*)min_val.ToPointer(), (double*)max_val.ToPointer(), (CvPoint*)min_loc.ToPointer(), (CvPoint*)max_val.ToPointer(), mask.ToPointer());
	}

	/// <summary>
	/// Finds global minimum, maximum and their positions
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="min_val"></param>
	/// <param name="max_val"></param>
	/// <param name="min_loc"></param>
	/// <param name="max_loc"></param>
	static void MinMaxLoc(IntPtr arr, IntPtr min_val, IntPtr max_val, IntPtr min_loc, IntPtr max_loc)
	{
		cvMinMaxLoc(arr.ToPointer(), (double*)min_val.ToPointer(), (double*)max_val.ToPointer(), (CvPoint*)min_loc.ToPointer(), (CvPoint*)max_loc.ToPointer());
	}

	/// <summary>
	/// Finds global minimum, maximum and their positions
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="min_val"></param>
	/// <param name="max_val"></param>
	/// <param name="min_loc"></param>
	static void MinMaxLoc(IntPtr arr, IntPtr min_val, IntPtr max_val, IntPtr min_loc)
	{
		cvMinMaxLoc(arr.ToPointer(), (double*)min_val.ToPointer(), (double*)max_val.ToPointer(), (CvPoint*)min_loc.ToPointer());
	}

	/// <summary>
	/// Finds global minimum, maximum and their positions
	/// </summary>
	/// <param name="arr"></param>
	/// <param name="min_val"></param>
	/// <param name="max_val"></param>
	static void MinMaxLoc(IntPtr arr, IntPtr min_val, IntPtr max_val)
	{
		cvMinMaxLoc(arr.ToPointer(), (double*)min_val.ToPointer(), (double*)max_val.ToPointer());
	}

	/// <summary>
	/// Finds norm, difference norm or relative difference norm for an array (or two arrays)
	/// </summary>
	/// <param name="arr1"></param>
	/// <param name="arr2"></param>
	/// <param name="norm_type"></param>
	/// <param name="mask"></param>
	/// <returns></returns>
	static double Norm(IntPtr arr1, IntPtr arr2, NormType norm_type, IntPtr mask)
	{
		return cvNorm(arr1.ToPointer(), arr2.ToPointer(), (int)norm_type, mask.ToPointer());
	}

	/// <summary>
	/// Finds norm, difference norm or relative difference norm for an array (or two arrays)
	/// </summary>
	/// <param name="arr1"></param>
	/// <param name="arr2"></param>
	/// <param name="norm_type"></param>
	/// <returns></returns>
	static double Norm(IntPtr arr1, IntPtr arr2, NormType norm_type)
	{
		return cvNorm(arr1.ToPointer(), arr2.ToPointer(), (int)norm_type);
	}

	/// <summary>
	/// Finds norm, difference norm or relative difference norm for an array (or two arrays)
	/// </summary>
	/// <param name="arr1"></param>
	/// <param name="arr2"></param>
	/// <returns></returns>
	static double Norm(IntPtr arr1, IntPtr arr2)
	{
		return cvNorm(arr1.ToPointer(), arr2.ToPointer());
	}

	/// <summary>
	/// Finds norm, difference norm or relative difference norm for an array (or two arrays)
	/// </summary>
	/// <param name="arr1"></param>
	/// <returns></returns>
	static double Norm(IntPtr arr1)
	{
		return cvNorm(arr1.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="a"></param>
	/// <param name="b"></param>
	/// <param name="norm_type"></param>
	/// <param name="mask"></param>
	static void Normalize(IntPtr src, IntPtr dst, double a, double b, NormType norm_type, IntPtr mask)
	{
		cvNormalize(src.ToPointer(), dst.ToPointer(), a, b, (int)norm_type, mask.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="a"></param>
	/// <param name="b"></param>
	/// <param name="norm_type"></param>
	static void Normalize(IntPtr src, IntPtr dst, double a, double b, NormType norm_type)
	{
		cvNormalize(src.ToPointer(), dst.ToPointer(), a, b, (int)norm_type);
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="a"></param>
	/// <param name="b"></param>
	static void Normalize(IntPtr src, IntPtr dst, double a, double b)
	{
		cvNormalize(src.ToPointer(), dst.ToPointer(), a, b);
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="a"></param>
	static void Normalize(IntPtr src, IntPtr dst, double a)
	{
		cvNormalize(src.ToPointer(), dst.ToPointer(), a);
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Normalize(IntPtr src, IntPtr dst)
	{
		cvNormalize(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="dim"></param>
	/// <param name="op"></param>
	static void Reduce(IntPtr src, IntPtr dst, int dim, ReduceType op)
	{
		cvReduce(src.ToPointer(), dst.ToPointer(), dim, (int)op);
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="dim"></param>
	static void Reduce(IntPtr src, IntPtr dst, int dim)
	{
		cvReduce(src.ToPointer(), dst.ToPointer(), dim);
	}

	/// <summary>
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void Reduce(IntPtr src, IntPtr dst)
	{
		cvReduce(src.ToPointer(), dst.ToPointer());
	}

	/// <summary>
	/// Discrete Fourier Transform:
	/// complex->complex,
	/// real->ccs (forward),
	/// ccs->real (inverse)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="flags"></param>
	/// <param name="nonzero_rows"></param>
	static void DFT(IntPtr src, IntPtr dst, DxtFlag flags, int nonzero_rows)
	{
		cvDFT(src.ToPointer(), dst.ToPointer(), (int)flags, nonzero_rows);
	}

	/// <summary>
	/// Discrete Fourier Transform:
	/// complex->complex,
	/// real->ccs (forward),
	/// ccs->real (inverse)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="flags"></param>
	static void DFT(IntPtr src, IntPtr dst, DxtFlag flags)
	{
		cvDFT(src.ToPointer(), dst.ToPointer(), (int)flags);
	}

	/// <summary>
	/// Discrete Fourier Transform:
	/// complex->complex,
	/// real->ccs (forward),
	/// ccs->real (inverse)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="flags"></param>
	/// <param name="nonzero_rows"></param>
	static void FFT(IntPtr src, IntPtr dst, DxtFlag flags, int nonzero_rows)
	{
		cvFFT(src.ToPointer(), dst.ToPointer(), (int)flags, nonzero_rows);
	}

	/// <summary>
	/// Discrete Fourier Transform:
	/// complex->complex,
	/// real->ccs (forward),
	/// ccs->real (inverse)
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="flags"></param>
	static void FFT(IntPtr src, IntPtr dst, DxtFlag flags)
	{
		cvFFT(src.ToPointer(), dst.ToPointer(), (int)flags);
	}

	/// <summary>
	/// Multiply results of DFTs: DFT(X)*DFT(Y) or DFT(X)*conj(DFT(Y))
	/// </summary>
	/// <param name="src1"></param>
	/// <param name="src2"></param>
	/// <param name="dst"></param>
	/// <param name="flags"></param>
	static void MulSpectrums(IntPtr src1, IntPtr src2, IntPtr dst, DxtFlag flags)
	{
		cvMulSpectrums(src1.ToPointer(), src2.ToPointer(), dst.ToPointer(), (int)flags);
	}

	/// <summary>
	/// Finds optimal DFT vector size >= size0
	/// </summary>
	/// <param name="size0"></param>
	/// <returns></returns>
	static int GetOptimalDFTSize(int size0)
	{
		return cvGetOptimalDFTSize(size0);
	}

	/// <summary>
	/// Discrete Cosine Transform
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	/// <param name="flags"></param>
	static void DCT(IntPtr src, IntPtr dst, DxtFlag flags)
	{
		cvDCT(src.ToPointer(), dst.ToPointer(), (int)flags);
	}

	/// <summary>
	/// Calculates length of sequence slice (with support of negative indices).
	/// </summary>
	/// <param name="slice"></param>
	/// <returns></returns>
	static int SliceLength(NAMESPACE::Slice slice, IntPtr seq)
	{
		return cvSliceLength(*(CvSlice*)&slice, (CvSeq*)seq.ToPointer());
	}

	/// <summary>
	/// Creates new memory storage.
	/// block_size == 0 means that default,
	/// somewhat optimal size, is used (currently, it is 64K)
	/// </summary>
	/// <returns></returns>
	static IntPtr CreateMemStorage(int block_size)
	{
		return IntPtr(cvCreateMemStorage(block_size));
	}

	/// <summary>
	/// Creates new memory storage.
	/// block_size == 0 means that default,
	/// somewhat optimal size, is used (currently, it is 64K)
	/// </summary>
	/// <returns></returns>
	static IntPtr CreateMemStorage()
	{
		return IntPtr(cvCreateMemStorage());
	}

	/// <summary>
	/// Creates a memory storage that will borrow memory blocks from parent storage
	/// </summary>
	/// <returns></returns>
	static IntPtr CreateChildMemStorage(IntPtr parent)
	{
		return IntPtr(cvCreateChildMemStorage((CvMemStorage*)parent.ToPointer()));
	}

	/// <summary>
	/// Releases memory storage. All the children of a parent must be released before
	/// the parent. A child storage returns all the blocks to parent when it is released
	/// </summary>
	static void ReleaseMemStorage(IntPtr storage)
	{
		cvReleaseMemStorage((CvMemStorage**)storage.ToPointer());
	}

	/// <summary>
	/// Clears memory storage. This is the only way(!!!) (besides cvRestoreMemStoragePos)
	/// to reuse memory allocated for the storage - cvClearSeq,cvClearSet ...
	/// do not free any memory.
	/// A child storage returns all the blocks to the parent when it is cleared
	/// </summary>
	static void ClearMemStorage(IntPtr storage)
	{
		cvClearMemStorage((CvMemStorage*)storage.ToPointer());
	}

	/// <summary>
	/// Remember a storage "free memory" position
	/// </summary>
	/// <param name="storage"></param>
	static void SaveMemStoragePos(IntPtr storage, IntPtr pos)
	{
		cvSaveMemStoragePos((CvMemStorage*)storage.ToPointer(), (CvMemStoragePos*)pos.ToPointer());
	}

	/// <summary>
	/// Restore a storage "free memory" position
	/// </summary>
	/// <param name="storage"></param>
	static void RestoreMemStoragePos(IntPtr storage, IntPtr pos)
	{
		cvRestoreMemStoragePos((CvMemStorage*)storage.ToPointer(), (CvMemStoragePos*)pos.ToPointer());
	}

	/// <summary>
	/// Allocates continuous buffer of the specified size in the storage
	/// </summary>
	/// <param name="storage"></param>
	/// <returns></returns>
	static IntPtr MemStorageAlloc(IntPtr storage, size_t size)
	{
		return IntPtr(cvMemStorageAlloc((CvMemStorage*)storage.ToPointer(), size));
	}

	/// <summary>
	/// Allocates string in memory storage
	/// </summary>
	/// <param name="storage"></param>
	/// <param name="ptr"></param>
	/// <returns></returns>
	static String MemStorageAllocString(IntPtr storage, IntPtr ptr, int len)
	{
		return *(String*)&cvMemStorageAllocString((CvMemStorage*)storage.ToPointer(), (char*)ptr.ToPointer(), len);
	}

	/// <summary>
	/// Allocates string in memory storage
	/// </summary>
	/// <param name="storage"></param>
	/// <returns></returns>
	static String MemStorageAllocString(IntPtr storage, IntPtr ptr)
	{
		return *(String*)&cvMemStorageAllocString((CvMemStorage*)storage.ToPointer(), (char*)ptr.ToPointer());
	}

	/// <summary>
	/// Creates new empty sequence that will reside in the specified storage
	/// </summary>
	/// <param name="seq_flags"></param>
	/// <param name="header_size"></param>
	/// <param name="elem_size"></param>
	/// <returns></returns>
	static IntPtr CreateSeq(SeqFlag seq_flags, int header_size, int elem_size, IntPtr storage)
	{
		return IntPtr(cvCreateSeq((int)seq_flags, header_size, elem_size, (CvMemStorage*)storage.ToPointer()));
	}

	/// <summary>
	/// Changes default size (granularity) of sequence blocks.
	/// The default size is ~1Kbyte
	/// </summary>
	/// <param name="seq"></param>
	static void SetSeqBlockSize(IntPtr seq, int delta_elems)
	{
		cvSetSeqBlockSize((CvSeq*)seq.ToPointer(), delta_elems);
	}

	/// <summary>
	/// Adds new element to the end of sequence. Returns pointer to the element
	/// </summary>
	/// <param name="seq"></param>
	/// <returns></returns>
	static IntPtr SeqPush(IntPtr seq, IntPtr element)
	{
		return IntPtr(cvSeqPush((CvSeq*)seq.ToPointer(), (void*)element.ToPointer()));
	}

	/// <summary>
	/// Adds new element to the end of sequence. Returns pointer to the element
	/// </summary>
	/// <returns></returns>
	static IntPtr SeqPush(IntPtr seq)
	{
		return IntPtr(cvSeqPush((CvSeq*)seq.ToPointer()));
	}

	/// <summary>
	/// Adds new element to the beginning of sequence. Returns pointer to it
	/// </summary>
	/// <param name="seq"></param>
	/// <returns></returns>
	static IntPtr SeqPushFront(IntPtr seq, IntPtr element)
	{
		return IntPtr(cvSeqPushFront((CvSeq*)seq.ToPointer(), (void*)element.ToPointer()));
	}

	/// <summary>
	/// Adds new element to the beginning of sequence. Returns pointer to it
	/// </summary>
	/// <returns></returns>
	static IntPtr SeqPushFront(IntPtr seq)
	{
		return IntPtr(cvSeqPushFront((CvSeq*)seq.ToPointer()));
	}

	/// <summary>
	/// Removes the last element from sequence and optionally saves it
	/// </summary>
	/// <param name="seq"></param>
	static void SeqPop(IntPtr seq, IntPtr element)
	{
		cvSeqPop((CvSeq*)seq.ToPointer(), (void*)element.ToPointer());
	}

	/// <summary>
	/// Removes the last element from sequence and optionally saves it
	/// </summary>
	static void SeqPop(IntPtr seq)
	{
		cvSeqPop((CvSeq*)seq.ToPointer());
	}

	/// <summary>
	/// Removes the first element from sequence and optioanally saves it
	/// </summary>
	/// <param name="seq"></param>
	static void SeqPopFront(IntPtr seq, IntPtr element)
	{
		cvSeqPopFront((CvSeq*)seq.ToPointer(), (void*)element.ToPointer());
	}

	/// <summary>
	/// Removes the first element from sequence and optioanally saves it
	/// </summary>
	static void SeqPopFront(IntPtr seq)
	{
		cvSeqPopFront((CvSeq*)seq.ToPointer());
	}

	/// <summary>
	/// Adds several new elements to the end of sequence
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="elements"></param>
	/// <param name="count"></param>
	static void SeqPushMulti(IntPtr seq, IntPtr elements, int count, bool in_front)
	{
		cvSeqPushMulti((CvSeq*)seq.ToPointer(), (void*)elements.ToPointer(), count, (int)in_front);
	}

	/// <summary>
	/// Adds several new elements to the end of sequence
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="elements"></param>
	static void SeqPushMulti(IntPtr seq, IntPtr elements, int count)
	{
		cvSeqPushMulti((CvSeq*)seq.ToPointer(), (void*)elements.ToPointer(), count);
	}

	/// <summary>
	/// Removes several elements from the end of sequence and optionally saves them
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="elements"></param>
	/// <param name="count"></param>
	static void SeqPopMulti(IntPtr seq, IntPtr elements, int count, bool in_front)
	{
		cvSeqPopMulti((CvSeq*)seq.ToPointer(), (void*)elements.ToPointer(), count, (int)in_front);
	}

	/// <summary>
	/// Removes several elements from the end of sequence and optionally saves them
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="elements"></param>
	static void SeqPopMulti(IntPtr seq, IntPtr elements, int count)
	{
		cvSeqPopMulti((CvSeq*)seq.ToPointer(), (void*)elements.ToPointer(), count);
	}

	/// <summary>
	/// Inserts a new element in the middle of sequence.
	/// cvSeqInsert(seq,0,elem) == cvSeqPushFront(seq,elem)
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="before_index"></param>
	/// <returns></returns>
	static IntPtr SeqInsert(IntPtr seq, int before_index, IntPtr element)
	{
		return IntPtr(cvSeqInsert((CvSeq*)seq.ToPointer(), before_index, (void*)element.ToPointer()));
	}

	/// <summary>
	/// Inserts a new element in the middle of sequence.
	/// cvSeqInsert(seq,0,elem) == cvSeqPushFront(seq,elem)
	/// </summary>
	/// <param name="seq"></param>
	/// <returns></returns>
	static IntPtr SeqInsert(IntPtr seq, int before_index)
	{
		return IntPtr(cvSeqInsert((CvSeq*)seq.ToPointer(), before_index));
	}

	/// <summary>
	/// Removes specified sequence element
	/// </summary>
	/// <param name="seq"></param>
	static void SeqRemove(IntPtr seq, int index)
	{
		cvSeqRemove((CvSeq*)seq.ToPointer(), index);
	}

	/// <summary>
	/// Removes all the elements from the sequence. The freed memory
	/// can be reused later only by the same sequence unless cvClearMemStorage
	/// or cvRestoreMemStoragePos is called
	/// </summary>
	static void ClearSeq(IntPtr seq)
	{
		cvClearSeq((CvSeq*)seq.ToPointer());
	}

	/// <summary>
	/// Retrieves pointer to specified sequence element.
	/// Negative indices are supported and mean counting from the end
	/// (e.g -1 means the last sequence element)
	/// </summary>
	/// <param name="seq"></param>
	/// <returns></returns>
	static IntPtr GetSeqElem(IntPtr seq, int index)
	{
		return IntPtr(cvGetSeqElem((CvSeq*)seq.ToPointer(), index));
	}

	/// <summary>
	/// Calculates index of the specified sequence element.
	/// Returns -1 if element does not belong to the sequence
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="element"></param>
	/// <returns></returns>
	static int SeqElemIdx(IntPtr seq, IntPtr element, IntPtr block)
	{
		return cvSeqElemIdx((CvSeq*)seq.ToPointer(), (void*)element.ToPointer(), (CvSeqBlock**)block.ToPointer());
	}

	/// <summary>
	/// Calculates index of the specified sequence element.
	/// Returns -1 if element does not belong to the sequence
	/// </summary>
	/// <param name="seq"></param>
	/// <returns></returns>
	static int SeqElemIdx(IntPtr seq, IntPtr element)
	{
		return cvSeqElemIdx((CvSeq*)seq.ToPointer(), (void*)element.ToPointer());
	}

	/// <summary>
	/// Initializes sequence writer. The new elements will be added to the end of sequence
	/// </summary>
	/// <param name="seq"></param>
	static void StartAppendToSeq(IntPtr seq, IntPtr writer)
	{
		cvStartAppendToSeq((CvSeq*)seq.ToPointer(), (CvSeqWriter*)writer.ToPointer());
	}

	/// <summary>
	/// Combination of cvCreateSeq and cvStartAppendToSeq
	/// </summary>
	/// <param name="seq_flags"></param>
	/// <param name="header_size"></param>
	/// <param name="elem_size"></param>
	/// <param name="storage"></param>
	static void StartWriteSeq(SeqFlag seq_flags, int header_size, int elem_size, IntPtr storage, IntPtr writer)
	{
		cvStartWriteSeq((int)seq_flags, header_size, elem_size, (CvMemStorage*)storage.ToPointer(), (CvSeqWriter*)writer.ToPointer());
	}

	/// <summary>
	/// Closes sequence writer, updates sequence header and returns pointer
	/// to the resultant sequence
	/// (which may be useful if the sequence was created using cvStartWriteSeq))
	/// </summary>
	/// <returns></returns>
	static IntPtr EndWriteSeq(IntPtr writer)
	{
		return IntPtr(cvEndWriteSeq((CvSeqWriter*)writer.ToPointer()));
	}

	/// <summary>
	/// Updates sequence header. May be useful to get access to some of previously
	/// written elements via cvGetSeqElem or sequence reader
	/// </summary>
	static void FlushSeqWriter(IntPtr writer)
	{
		cvFlushSeqWriter((CvSeqWriter*)writer.ToPointer());
	}

	/// <summary>
	/// Initializes sequence reader.
	/// The sequence can be read in forward or backward direction
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="reader"></param>
	static void StartReadSeq(IntPtr seq, IntPtr reader, bool reverse)
	{
		cvStartReadSeq((CvSeq*)seq.ToPointer(), (CvSeqReader*)reader.ToPointer(), (int)reverse);
	}

	/// <summary>
	/// Initializes sequence reader.
	/// The sequence can be read in forward or backward direction
	/// </summary>
	/// <param name="seq"></param>
	static void StartReadSeq(IntPtr seq, IntPtr reader)
	{
		cvStartReadSeq((CvSeq*)seq.ToPointer(), (CvSeqReader*)reader.ToPointer());
	}

	/// <summary>
	/// Returns current sequence reader position (currently observed sequence element)
	/// </summary>
	/// <returns></returns>
	static int GetSeqReaderPos(IntPtr reader)
	{
		return cvGetSeqReaderPos((CvSeqReader*)reader.ToPointer());
	}

	/// <summary>
	/// Changes sequence reader position. It may seek to an absolute or
	/// to relative to the current position
	/// </summary>
	/// <param name="reader"></param>
	/// <param name="index"></param>
	static void SetSeqReaderPos(IntPtr reader, int index, bool is_relative)
	{
		cvSetSeqReaderPos((CvSeqReader*)reader.ToPointer(), index, (int)is_relative);
	}

	/// <summary>
	/// Changes sequence reader position. It may seek to an absolute or
	/// to relative to the current position
	/// </summary>
	/// <param name="reader"></param>
	static void SetSeqReaderPos(IntPtr reader, int index)
	{
		cvSetSeqReaderPos((CvSeqReader*)reader.ToPointer(), index);
	}

	/// <summary>
	/// Copies sequence content to a continuous piece of memory
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="elements"></param>
	/// <returns></returns>
	static IntPtr CvtSeqToArray(IntPtr seq, IntPtr elements, NAMESPACE::Slice slice)
	{
		return IntPtr(cvCvtSeqToArray((CvSeq*)seq.ToPointer(), (void*)elements.ToPointer(), *(CvSlice*)&slice));
	}

	/// <summary>
	/// Copies sequence content to a continuous piece of memory
	/// </summary>
	/// <param name="seq"></param>
	/// <returns></returns>
	static IntPtr CvtSeqToArray(IntPtr seq, IntPtr elements)
	{
		return IntPtr(cvCvtSeqToArray((CvSeq*)seq.ToPointer(), (void*)elements.ToPointer()));
	}

	/// <summary>
	/// Creates sequence header for array.
	/// After that all the operations on sequences that do not alter the content
	/// can be applied to the resultant sequence
	/// </summary>
	/// <param name="seq_type"></param>
	/// <param name="header_size"></param>
	/// <param name="elem_size"></param>
	/// <param name="elements"></param>
	/// <param name="total"></param>
	/// <param name="seq"></param>
	/// <returns></returns>
	static IntPtr MakeSeqHeaderForArray(SeqFlag seq_type, int header_size, int elem_size, IntPtr elements, int total, IntPtr seq, IntPtr block)
	{
		return IntPtr(cvMakeSeqHeaderForArray((int)seq_type, header_size, elem_size, (void*)elements.ToPointer(), total, (CvSeq*)seq.ToPointer(), (CvSeqBlock*)block.ToPointer()));
	}

	/// <summary>
	/// Extracts sequence slice (with or without copying sequence elements)
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="slice"></param>
	/// <param name="storage"></param>
	/// <returns></returns>
	static IntPtr SeqSlice(IntPtr seq, NAMESPACE::Slice slice, IntPtr storage, bool copy_data)
	{
		return IntPtr(cvSeqSlice((CvSeq*)seq.ToPointer(), *(CvSlice*)&slice, (CvMemStorage*)storage.ToPointer(), (int)copy_data));
	}

	/// <summary>
	/// Extracts sequence slice (with or without copying sequence elements)
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="slice"></param>
	/// <returns></returns>
	static IntPtr SeqSlice(IntPtr seq, NAMESPACE::Slice slice, IntPtr storage)
	{
		return IntPtr(cvSeqSlice((CvSeq*)seq.ToPointer(), *(CvSlice*)&slice, (CvMemStorage*)storage.ToPointer()));
	}

	/// <summary>
	/// Extracts sequence slice (with or without copying sequence elements)
	/// </summary>
	/// <param name="seq"></param>
	/// <returns></returns>
	static IntPtr SeqSlice(IntPtr seq, NAMESPACE::Slice slice)
	{
		return IntPtr(cvSeqSlice((CvSeq*)seq.ToPointer(), *(CvSlice*)&slice));
	}

	/// <summary>
	/// Removes sequence slice
	/// </summary>
	/// <param name="seq"></param>
	static void SeqRemoveSlice(IntPtr seq, NAMESPACE::Slice slice)
	{
		cvSeqRemoveSlice((CvSeq*)seq.ToPointer(), *(CvSlice*)&slice);
	}

	/// <summary>
	/// Inserts a sequence or array into another sequence
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="before_index"></param>
	static void SeqInsertSlice(IntPtr seq, int before_index, IntPtr from_arr)
	{
		cvSeqInsertSlice((CvSeq*)seq.ToPointer(), before_index, (CvArr*)from_arr.ToPointer());
	}

	/// <summary>
	/// Sorts sequence in-place given element comparison function
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="func"></param>
	static void SeqSort(IntPtr seq, CmpFunc^ func, IntPtr userdata)
	{
		cvSeqSort((CvSeq*)seq.ToPointer(), (CvCmpFunc)Marshal::GetFunctionPointerForDelegate(func).ToPointer(), (void*)userdata.ToPointer());
	}

	/// <summary>
	/// Sorts sequence in-place given element comparison function
	/// </summary>
	/// <param name="seq"></param>
	static void SeqSort(IntPtr seq, CmpFunc^ func)
	{
		cvSeqSort((CvSeq*)seq.ToPointer(), (CvCmpFunc)Marshal::GetFunctionPointerForDelegate(func).ToPointer());
	}

	/// <summary>
	/// Finds element in a [sorted] sequence
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="elem"></param>
	/// <param name="func"></param>
	/// <param name="is_sorted"></param>
	/// <param name="elem_idx"></param>
	/// <returns></returns>
	static IntPtr SeqSearch(IntPtr seq, IntPtr elem, CmpFunc^ func, int is_sorted, IntPtr elem_idx, IntPtr userdata)
	{
		return IntPtr(cvSeqSearch((CvSeq*)seq.ToPointer(), (void*)elem.ToPointer(), (CvCmpFunc)Marshal::GetFunctionPointerForDelegate(func).ToPointer(), is_sorted, (int*)elem_idx.ToPointer(), (void*)userdata.ToPointer()));
	}

	/// <summary>
	/// Finds element in a [sorted] sequence
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="elem"></param>
	/// <param name="func"></param>
	/// <param name="is_sorted"></param>
	/// <returns></returns>
	static IntPtr SeqSearch(IntPtr seq, IntPtr elem, CmpFunc^ func, int is_sorted, IntPtr elem_idx)
	{
		return IntPtr(cvSeqSearch((CvSeq*)seq.ToPointer(), (void*)elem.ToPointer(), (CvCmpFunc)Marshal::GetFunctionPointerForDelegate(func).ToPointer(), is_sorted, (int*)elem_idx.ToPointer()));
	}

	/// <summary>
	/// Reverses order of sequence elements in-place
	/// </summary>
	static void SeqInvert(IntPtr seq)
	{
		cvSeqInvert((CvSeq*)seq.ToPointer());
	}

	/// <summary>
	/// Splits sequence into one or more equivalence classes using the specified criteria
	/// </summary>
	/// <param name="seq"></param>
	/// <param name="storage"></param>
	/// <param name="labels"></param>
	/// <param name="is_equal"></param>
	/// <returns></returns>
	static int SeqPartition(IntPtr seq, IntPtr storage, IntPtr labels, CmpFunc^ is_equal, IntPtr userdata)
	{
		return cvSeqPartition((CvSeq*)seq.ToPointer(), (CvMemStorage*)storage.ToPointer(), (CvSeq**)labels.ToPointer(), (CvCmpFunc)Marshal::GetFunctionPointerForDelegate(is_equal).ToPointer(), (void*)userdata.ToPointer());
	}

	/// <summary>
	/// Internal sequence functions
	/// </summary>
	/// <param name="reader"></param>
	static void ChangeSeqBlock(IntPtr reader, int direction)
	{
		cvChangeSeqBlock((void*)reader.ToPointer(), direction);
	}

	/// <summary>
	/// </summary>
	static void CreateSeqBlock(IntPtr writer)
	{
		cvCreateSeqBlock((CvSeqWriter*)writer.ToPointer());
	}

	/// <summary>
	/// Creates a new set
	/// </summary>
	/// <param name="set_flags"></param>
	/// <param name="header_size"></param>
	/// <param name="elem_size"></param>
	/// <returns></returns>
	static IntPtr CreateSet(int set_flags, int header_size, int elem_size, IntPtr storage)
	{
		return IntPtr(cvCreateSet(set_flags, header_size, elem_size, (CvMemStorage*)storage.ToPointer()));
	}

	/// <summary>
	/// Adds new element to the set and returns pointer to it
	/// </summary>
	/// <param name="set_header"></param>
	/// <param name="elem"></param>
	/// <returns></returns>
	static int SetAdd(IntPtr set_header, IntPtr elem, IntPtr inserted_elem)
	{
		return cvSetAdd((CvSet*)set_header.ToPointer(), (CvSetElem*)elem.ToPointer(), (CvSetElem**)inserted_elem.ToPointer());
	}

	/// <summary>
	/// Adds new element to the set and returns pointer to it
	/// </summary>
	/// <param name="set_header"></param>
	/// <returns></returns>
	static int SetAdd(IntPtr set_header, IntPtr elem)
	{
		return cvSetAdd((CvSet*)set_header.ToPointer(), (CvSetElem*)elem.ToPointer());
	}

	/// <summary>
	/// Adds new element to the set and returns pointer to it
	/// </summary>
	/// <returns></returns>
	static int SetAdd(IntPtr set_header)
	{
		return cvSetAdd((CvSet*)set_header.ToPointer());
	}

	/// <summary>
	/// Removes element from the set by its index
	/// </summary>
	/// <param name="set_header"></param>
	static void SetRemove(IntPtr set_header, int index)
	{
		cvSetRemove((CvSet*)set_header.ToPointer(), index);
	}

	/// <summary>
	/// Removes all the elements from the set
	/// </summary>
	static void ClearSet(IntPtr set_header)
	{
		cvClearSet((CvSet*)set_header.ToPointer());
	}

	/// <summary>
	/// Creates new graph
	/// </summary>
	/// <param name="graph_flags"></param>
	/// <param name="header_size"></param>
	/// <param name="vtx_size"></param>
	/// <param name="edge_size"></param>
	/// <returns></returns>
	static IntPtr CreateGraph(int graph_flags, int header_size, int vtx_size, int edge_size, IntPtr storage)
	{
		return IntPtr(cvCreateGraph(graph_flags, header_size, vtx_size, edge_size, (CvMemStorage*)storage.ToPointer()));
	}

	/// <summary>
	/// Adds new vertex to the graph
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="vtx"></param>
	/// <returns></returns>
	static int GraphAddVtx(IntPtr graph, IntPtr vtx, IntPtr inserted_vtx)
	{
		return cvGraphAddVtx((CvGraph*)graph.ToPointer(), (CvGraphVtx*)vtx.ToPointer(), (CvGraphVtx**)inserted_vtx.ToPointer());
	}

	/// <summary>
	/// Adds new vertex to the graph
	/// </summary>
	/// <param name="graph"></param>
	/// <returns></returns>
	static int GraphAddVtx(IntPtr graph, IntPtr vtx)
	{
		return cvGraphAddVtx((CvGraph*)graph.ToPointer(), (CvGraphVtx*)vtx.ToPointer());
	}

	/// <summary>
	/// Adds new vertex to the graph
	/// </summary>
	/// <returns></returns>
	static int GraphAddVtx(IntPtr graph)
	{
		return cvGraphAddVtx((CvGraph*)graph.ToPointer());
	}

	/// <summary>
	/// Removes vertex from the graph together with all incident edges
	/// </summary>
	/// <param name="graph"></param>
	/// <returns></returns>
	static int GraphRemoveVtx(IntPtr graph, int index)
	{
		return cvGraphRemoveVtx((CvGraph*)graph.ToPointer(), index);
	}

	/// <summary>
	/// </summary>
	/// <param name="graph"></param>
	/// <returns></returns>
	static int GraphRemoveVtxByPtr(IntPtr graph, IntPtr vtx)
	{
		return cvGraphRemoveVtxByPtr((CvGraph*)graph.ToPointer(), (CvGraphVtx*)vtx.ToPointer());
	}

	/// <summary>
	/// Link two vertices specifed by indices or pointers if they
	/// are not connected or return pointer to already existing edge
	/// connecting the vertices.
	/// Functions return 1 if a new edge was created, 0 otherwise
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_idx"></param>
	/// <param name="end_idx"></param>
	/// <param name="edge"></param>
	/// <returns></returns>
	static int GraphAddEdge(IntPtr graph, int start_idx, int end_idx, IntPtr edge, IntPtr inserted_edge)
	{
		return cvGraphAddEdge((CvGraph*)graph.ToPointer(), start_idx, end_idx, (CvGraphEdge*)edge.ToPointer(), (CvGraphEdge**)inserted_edge.ToPointer());
	}

	/// <summary>
	/// Link two vertices specifed by indices or pointers if they
	/// are not connected or return pointer to already existing edge
	/// connecting the vertices.
	/// Functions return 1 if a new edge was created, 0 otherwise
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_idx"></param>
	/// <param name="end_idx"></param>
	/// <returns></returns>
	static int GraphAddEdge(IntPtr graph, int start_idx, int end_idx, IntPtr edge)
	{
		return cvGraphAddEdge((CvGraph*)graph.ToPointer(), start_idx, end_idx, (CvGraphEdge*)edge.ToPointer());
	}

	/// <summary>
	/// Link two vertices specifed by indices or pointers if they
	/// are not connected or return pointer to already existing edge
	/// connecting the vertices.
	/// Functions return 1 if a new edge was created, 0 otherwise
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_idx"></param>
	/// <returns></returns>
	static int GraphAddEdge(IntPtr graph, int start_idx, int end_idx)
	{
		return cvGraphAddEdge((CvGraph*)graph.ToPointer(), start_idx, end_idx);
	}

	/// <summary>
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_vtx"></param>
	/// <param name="end_vtx"></param>
	/// <param name="edge"></param>
	/// <returns></returns>
	static int GraphAddEdgeByPtr(IntPtr graph, IntPtr start_vtx, IntPtr end_vtx, IntPtr edge, IntPtr inserted_edge)
	{
		return cvGraphAddEdgeByPtr((CvGraph*)graph.ToPointer(), (CvGraphVtx*)start_vtx.ToPointer(), (CvGraphVtx*)end_vtx.ToPointer(), (CvGraphEdge*)edge.ToPointer(), (CvGraphEdge**)inserted_edge.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_vtx"></param>
	/// <param name="end_vtx"></param>
	/// <returns></returns>
	static int GraphAddEdgeByPtr(IntPtr graph, IntPtr start_vtx, IntPtr end_vtx, IntPtr edge)
	{
		return cvGraphAddEdgeByPtr((CvGraph*)graph.ToPointer(), (CvGraphVtx*)start_vtx.ToPointer(), (CvGraphVtx*)end_vtx.ToPointer(), (CvGraphEdge*)edge.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_vtx"></param>
	/// <returns></returns>
	static int GraphAddEdgeByPtr(IntPtr graph, IntPtr start_vtx, IntPtr end_vtx)
	{
		return cvGraphAddEdgeByPtr((CvGraph*)graph.ToPointer(), (CvGraphVtx*)start_vtx.ToPointer(), (CvGraphVtx*)end_vtx.ToPointer());
	}

	/// <summary>
	/// Remove edge connecting two vertices
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_idx"></param>
	static void GraphRemoveEdge(IntPtr graph, int start_idx, int end_idx)
	{
		cvGraphRemoveEdge((CvGraph*)graph.ToPointer(), start_idx, end_idx);
	}

	/// <summary>
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_vtx"></param>
	static void GraphRemoveEdgeByPtr(IntPtr graph, IntPtr start_vtx, IntPtr end_vtx)
	{
		cvGraphRemoveEdgeByPtr((CvGraph*)graph.ToPointer(), (CvGraphVtx*)start_vtx.ToPointer(), (CvGraphVtx*)end_vtx.ToPointer());
	}

	/// <summary>
	/// Find edge connecting two vertices
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_idx"></param>
	/// <returns></returns>
	static IntPtr FindGraphEdge(IntPtr graph, int start_idx, int end_idx)
	{
		return IntPtr(cvFindGraphEdge((CvGraph*)graph.ToPointer(), start_idx, end_idx));
	}

	/// <summary>
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_vtx"></param>
	/// <returns></returns>
	static IntPtr FindGraphEdgeByPtr(IntPtr graph, IntPtr start_vtx, IntPtr end_vtx)
	{
		return IntPtr(cvFindGraphEdgeByPtr((CvGraph*)graph.ToPointer(), (CvGraphVtx*)start_vtx.ToPointer(), (CvGraphVtx*)end_vtx.ToPointer()));
	}

	/// <summary>
	/// Find edge connecting two vertices
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_idx"></param>
	/// <returns></returns>
	static IntPtr GraphFindEdge(IntPtr graph, int start_idx, int end_idx)
	{
		return IntPtr(cvFindGraphEdge((CvGraph*)graph.ToPointer(), start_idx, end_idx));
	}

	/// <summary>
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="start_vtx"></param>
	/// <returns></returns>
	static IntPtr GraphFindEdgeByPtr(IntPtr graph, IntPtr start_vtx, IntPtr end_vtx)
	{
		return IntPtr(cvFindGraphEdgeByPtr((CvGraph*)graph.ToPointer(), (CvGraphVtx*)start_vtx.ToPointer(), (CvGraphVtx*)end_vtx.ToPointer()));
	}

	/// <summary>
	/// Remove all vertices and edges from the graph
	/// </summary>
	static void ClearGraph(IntPtr graph)
	{
		cvClearGraph((CvGraph*)graph.ToPointer());
	}

	/// <summary>
	/// Count number of edges incident to the vertex
	/// </summary>
	/// <param name="graph"></param>
	/// <returns></returns>
	static int GraphVtxDegree(IntPtr graph, int vtx_idx)
	{
		return cvGraphVtxDegree((CvGraph*)graph.ToPointer(), vtx_idx);
	}

	/// <summary>
	/// </summary>
	/// <param name="graph"></param>
	/// <returns></returns>
	static int GraphVtxDegreeByPtr(IntPtr graph, IntPtr vtx)
	{
		return cvGraphVtxDegreeByPtr((CvGraph*)graph.ToPointer(), (CvGraphVtx*)vtx.ToPointer());
	}

	/// <summary>
	/// Creates new graph scanner.
	/// </summary>
	/// <param name="graph"></param>
	/// <param name="vtx"></param>
	/// <returns></returns>
	static IntPtr CreateGraphScanner(IntPtr graph, IntPtr vtx, int mask)
	{
		return IntPtr(cvCreateGraphScanner((CvGraph*)graph.ToPointer(), (CvGraphVtx*)vtx.ToPointer(), mask));
	}

	/// <summary>
	/// Creates new graph scanner.
	/// </summary>
	/// <param name="graph"></param>
	/// <returns></returns>
	static IntPtr CreateGraphScanner(IntPtr graph, IntPtr vtx)
	{
		return IntPtr(cvCreateGraphScanner((CvGraph*)graph.ToPointer(), (CvGraphVtx*)vtx.ToPointer()));
	}

	/// <summary>
	/// Creates new graph scanner.
	/// </summary>
	/// <returns></returns>
	static IntPtr CreateGraphScanner(IntPtr graph)
	{
		return IntPtr(cvCreateGraphScanner((CvGraph*)graph.ToPointer()));
	}

	/// <summary>
	/// Releases graph scanner.
	/// </summary>
	static void ReleaseGraphScanner(IntPtr scanner)
	{
		cvReleaseGraphScanner((CvGraphScanner**)scanner.ToPointer());
	}

	/// <summary>
	/// Get next graph element
	/// </summary>
	/// <returns></returns>
	static int NextGraphItem(IntPtr scanner)
	{
		return cvNextGraphItem((CvGraphScanner*)scanner.ToPointer());
	}

	/// <summary>
	/// Creates a copy of graph
	/// </summary>
	/// <param name="graph"></param>
	/// <returns></returns>
	static IntPtr CloneGraph(IntPtr graph, IntPtr storage)
	{
		return IntPtr(cvCloneGraph((CvGraph*)graph.ToPointer(), (CvMemStorage*)storage.ToPointer()));
	}

	/// <summary>
	/// Draws 4-connected, 8-connected or antialiased line segment connecting two points
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void Line(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvLine((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws 4-connected, 8-connected or antialiased line segment connecting two points
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void Line(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvLine((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws 4-connected, 8-connected or antialiased line segment connecting two points
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	static void Line(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness)
	{
		cvLine((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws 4-connected, 8-connected or antialiased line segment connecting two points
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	static void Line(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color)
	{
		cvLine((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
	/// if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void Rectangle(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvRectangle((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
	/// if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void Rectangle(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvRectangle((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
	/// if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	static void Rectangle(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness)
	{
		cvRectangle((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
	/// if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	static void Rectangle(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color)
	{
		cvRectangle((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws a circle with specified center and radius.
	/// Thickness works in the same way as with cvRectangle
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="radius"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void Circle(IntPtr img, NAMESPACE::Point2D32s center, int radius, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvCircle((CvArr*)img.ToPointer(), *(CvPoint*)&center, radius, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws a circle with specified center and radius.
	/// Thickness works in the same way as with cvRectangle
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="radius"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void Circle(IntPtr img, NAMESPACE::Point2D32s center, int radius, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvCircle((CvArr*)img.ToPointer(), *(CvPoint*)&center, radius, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws a circle with specified center and radius.
	/// Thickness works in the same way as with cvRectangle
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="radius"></param>
	/// <param name="color"></param>
	static void Circle(IntPtr img, NAMESPACE::Point2D32s center, int radius, NAMESPACE::Scalar color, int thickness)
	{
		cvCircle((CvArr*)img.ToPointer(), *(CvPoint*)&center, radius, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws a circle with specified center and radius.
	/// Thickness works in the same way as with cvRectangle
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="radius"></param>
	static void Circle(IntPtr img, NAMESPACE::Point2D32s center, int radius, NAMESPACE::Scalar color)
	{
		cvCircle((CvArr*)img.ToPointer(), *(CvPoint*)&center, radius, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
	/// depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
	/// is rotated by <angle>. All the angles are in degrees
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="start_angle"></param>
	/// <param name="end_angle"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void Ellipse(IntPtr img, NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, double angle, double start_angle, double end_angle, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvEllipse((CvArr*)img.ToPointer(), *(CvPoint*)&center, *(CvSize*)&axes, angle, start_angle, end_angle, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
	/// depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
	/// is rotated by <angle>. All the angles are in degrees
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="start_angle"></param>
	/// <param name="end_angle"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void Ellipse(IntPtr img, NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, double angle, double start_angle, double end_angle, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvEllipse((CvArr*)img.ToPointer(), *(CvPoint*)&center, *(CvSize*)&axes, angle, start_angle, end_angle, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
	/// depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
	/// is rotated by <angle>. All the angles are in degrees
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="start_angle"></param>
	/// <param name="end_angle"></param>
	/// <param name="color"></param>
	static void Ellipse(IntPtr img, NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, double angle, double start_angle, double end_angle, NAMESPACE::Scalar color, int thickness)
	{
		cvEllipse((CvArr*)img.ToPointer(), *(CvPoint*)&center, *(CvSize*)&axes, angle, start_angle, end_angle, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
	/// depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
	/// is rotated by <angle>. All the angles are in degrees
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="start_angle"></param>
	/// <param name="end_angle"></param>
	static void Ellipse(IntPtr img, NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, double angle, double start_angle, double end_angle, NAMESPACE::Scalar color)
	{
		cvEllipse((CvArr*)img.ToPointer(), *(CvPoint*)&center, *(CvSize*)&axes, angle, start_angle, end_angle, *(CvScalar*)&color);
	}

	/// <summary>
	/// Fills convex or monotonous polygon.
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="color"></param>
	/// <param name="line_type"></param>
	static void FillConvexPoly(IntPtr img, IntPtr pts, int npts, NAMESPACE::Scalar color, LineTypeFlag line_type, int shift)
	{
		cvFillConvexPoly((CvArr*)img.ToPointer(), (CvPoint*)pts.ToPointer(), npts, *(CvScalar*)&color, (int)line_type, shift);
	}

	/// <summary>
	/// Fills convex or monotonous polygon.
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="color"></param>
	static void FillConvexPoly(IntPtr img, IntPtr pts, int npts, NAMESPACE::Scalar color, LineTypeFlag line_type)
	{
		cvFillConvexPoly((CvArr*)img.ToPointer(), (CvPoint*)pts.ToPointer(), npts, *(CvScalar*)&color, (int)line_type);
	}

	/// <summary>
	/// Fills convex or monotonous polygon.
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	static void FillConvexPoly(IntPtr img, IntPtr pts, int npts, NAMESPACE::Scalar color)
	{
		cvFillConvexPoly((CvArr*)img.ToPointer(), (CvPoint*)pts.ToPointer(), npts, *(CvScalar*)&color);
	}

	/// <summary>
	/// Fills an area bounded by one or more arbitrary polygons
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="color"></param>
	/// <param name="line_type"></param>
	static void FillPoly(IntPtr img, IntPtr pts, IntPtr npts, int contours, NAMESPACE::Scalar color, LineTypeFlag line_type, int shift)
	{
		cvFillPoly((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, *(CvScalar*)&color, (int)line_type, shift);
	}

	/// <summary>
	/// Fills an area bounded by one or more arbitrary polygons
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="color"></param>
	static void FillPoly(IntPtr img, IntPtr pts, IntPtr npts, int contours, NAMESPACE::Scalar color, LineTypeFlag line_type)
	{
		cvFillPoly((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, *(CvScalar*)&color, (int)line_type);
	}

	/// <summary>
	/// Fills an area bounded by one or more arbitrary polygons
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	static void FillPoly(IntPtr img, IntPtr pts, IntPtr npts, int contours, NAMESPACE::Scalar color)
	{
		cvFillPoly((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws one or more polygonal curves
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="is_closed"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void PolyLine(IntPtr img, IntPtr pts, IntPtr npts, int contours, bool is_closed, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvPolyLine((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, (int)is_closed, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws one or more polygonal curves
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="is_closed"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void PolyLine(IntPtr img, IntPtr pts, IntPtr npts, int contours, bool is_closed, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvPolyLine((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, (int)is_closed, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws one or more polygonal curves
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="is_closed"></param>
	/// <param name="color"></param>
	static void PolyLine(IntPtr img, IntPtr pts, IntPtr npts, int contours, bool is_closed, NAMESPACE::Scalar color, int thickness)
	{
		cvPolyLine((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, (int)is_closed, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws one or more polygonal curves
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="is_closed"></param>
	static void PolyLine(IntPtr img, IntPtr pts, IntPtr npts, int contours, bool is_closed, NAMESPACE::Scalar color)
	{
		cvPolyLine((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, (int)is_closed, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws 4-connected, 8-connected or antialiased line segment connecting two points
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void DrawLine(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvDrawLine((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws 4-connected, 8-connected or antialiased line segment connecting two points
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void DrawLine(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvDrawLine((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws 4-connected, 8-connected or antialiased line segment connecting two points
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	static void DrawLine(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness)
	{
		cvDrawLine((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws 4-connected, 8-connected or antialiased line segment connecting two points
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	static void DrawLine(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color)
	{
		cvDrawLine((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
	/// if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void DrawRect(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvDrawRect((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
	/// if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void DrawRect(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvDrawRect((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
	/// if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="color"></param>
	static void DrawRect(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color, int thickness)
	{
		cvDrawRect((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws a rectangle given two opposite corners of the rectangle (pt1 & pt2),
	/// if thickness<0 (e.g. thickness == CV_FILLED), the filled box is drawn
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	static void DrawRect(IntPtr img, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, NAMESPACE::Scalar color)
	{
		cvDrawRect((CvArr*)img.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws a circle with specified center and radius.
	/// Thickness works in the same way as with cvRectangle
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="radius"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void DrawCircle(IntPtr img, NAMESPACE::Point2D32s center, int radius, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvDrawCircle((CvArr*)img.ToPointer(), *(CvPoint*)&center, radius, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws a circle with specified center and radius.
	/// Thickness works in the same way as with cvRectangle
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="radius"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void DrawCircle(IntPtr img, NAMESPACE::Point2D32s center, int radius, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvDrawCircle((CvArr*)img.ToPointer(), *(CvPoint*)&center, radius, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws a circle with specified center and radius.
	/// Thickness works in the same way as with cvRectangle
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="radius"></param>
	/// <param name="color"></param>
	static void DrawCircle(IntPtr img, NAMESPACE::Point2D32s center, int radius, NAMESPACE::Scalar color, int thickness)
	{
		cvDrawCircle((CvArr*)img.ToPointer(), *(CvPoint*)&center, radius, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws a circle with specified center and radius.
	/// Thickness works in the same way as with cvRectangle
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="radius"></param>
	static void DrawCircle(IntPtr img, NAMESPACE::Point2D32s center, int radius, NAMESPACE::Scalar color)
	{
		cvDrawCircle((CvArr*)img.ToPointer(), *(CvPoint*)&center, radius, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
	/// depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
	/// is rotated by <angle>. All the angles are in degrees
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="start_angle"></param>
	/// <param name="end_angle"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void DrawEllipse(IntPtr img, NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, double angle, double start_angle, double end_angle, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvDrawEllipse((CvArr*)img.ToPointer(), *(CvPoint*)&center, *(CvSize*)&axes, angle, start_angle, end_angle, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
	/// depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
	/// is rotated by <angle>. All the angles are in degrees
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="start_angle"></param>
	/// <param name="end_angle"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void DrawEllipse(IntPtr img, NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, double angle, double start_angle, double end_angle, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvDrawEllipse((CvArr*)img.ToPointer(), *(CvPoint*)&center, *(CvSize*)&axes, angle, start_angle, end_angle, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
	/// depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
	/// is rotated by <angle>. All the angles are in degrees
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="start_angle"></param>
	/// <param name="end_angle"></param>
	/// <param name="color"></param>
	static void DrawEllipse(IntPtr img, NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, double angle, double start_angle, double end_angle, NAMESPACE::Scalar color, int thickness)
	{
		cvDrawEllipse((CvArr*)img.ToPointer(), *(CvPoint*)&center, *(CvSize*)&axes, angle, start_angle, end_angle, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws ellipse outline, filled ellipse, elliptic arc or filled elliptic sector,
	/// depending on <thickness>, <start_angle> and <end_angle> parameters. The resultant figure
	/// is rotated by <angle>. All the angles are in degrees
	/// </summary>
	/// <param name="img"></param>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="start_angle"></param>
	/// <param name="end_angle"></param>
	static void DrawEllipse(IntPtr img, NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, double angle, double start_angle, double end_angle, NAMESPACE::Scalar color)
	{
		cvDrawEllipse((CvArr*)img.ToPointer(), *(CvPoint*)&center, *(CvSize*)&axes, angle, start_angle, end_angle, *(CvScalar*)&color);
	}

	/// <summary>
	/// Draws one or more polygonal curves
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="is_closed"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void DrawPolyLine(IntPtr img, IntPtr pts, IntPtr npts, int contours, int is_closed, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type, int shift)
	{
		cvDrawPolyLine((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, is_closed, *(CvScalar*)&color, thickness, (int)line_type, shift);
	}

	/// <summary>
	/// Draws one or more polygonal curves
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="is_closed"></param>
	/// <param name="color"></param>
	/// <param name="thickness"></param>
	static void DrawPolyLine(IntPtr img, IntPtr pts, IntPtr npts, int contours, int is_closed, NAMESPACE::Scalar color, int thickness, LineTypeFlag line_type)
	{
		cvDrawPolyLine((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, is_closed, *(CvScalar*)&color, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws one or more polygonal curves
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="is_closed"></param>
	/// <param name="color"></param>
	static void DrawPolyLine(IntPtr img, IntPtr pts, IntPtr npts, int contours, int is_closed, NAMESPACE::Scalar color, int thickness)
	{
		cvDrawPolyLine((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, is_closed, *(CvScalar*)&color, thickness);
	}

	/// <summary>
	/// Draws one or more polygonal curves
	/// </summary>
	/// <param name="img"></param>
	/// <param name="pts"></param>
	/// <param name="npts"></param>
	/// <param name="contours"></param>
	/// <param name="is_closed"></param>
	static void DrawPolyLine(IntPtr img, IntPtr pts, IntPtr npts, int contours, int is_closed, NAMESPACE::Scalar color)
	{
		cvDrawPolyLine((CvArr*)img.ToPointer(), (CvPoint**)pts.ToPointer(), (int*)npts.ToPointer(), contours, is_closed, *(CvScalar*)&color);
	}

	/// <summary>
	/// Clips the line segment connecting *pt1 and *pt2
	/// by the rectangular window
	/// (0<=x<img_size.width, 0<=y<img_size.height).
	/// </summary>
	/// <param name="img_size"></param>
	/// <param name="pt1"></param>
	/// <returns></returns>
	static int ClipLine(CvSize img_size, IntPtr pt1, IntPtr pt2)
	{
		return cvClipLine(img_size, (CvPoint*)pt1.ToPointer(), (CvPoint*)pt2.ToPointer());
	}

	/// <summary>
	/// Initializes line iterator. Initially, line_iterator->ptr will point
	/// to pt1 (or pt2, see left_to_right description) location in the image.
	/// Returns the number of pixels on the line between the ending points.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="line_iterator"></param>
	/// <param name="connectivity"></param>
	/// <returns></returns>
	static int InitLineIterator(IntPtr image, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, IntPtr line_iterator, PixelConnectType connectivity, int left_to_right)
	{
		return cvInitLineIterator((CvArr*)image.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, (CvLineIterator*)line_iterator.ToPointer(), (int)connectivity, left_to_right);
	}

	/// <summary>
	/// Initializes line iterator. Initially, line_iterator->ptr will point
	/// to pt1 (or pt2, see left_to_right description) location in the image.
	/// Returns the number of pixels on the line between the ending points.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <param name="line_iterator"></param>
	/// <returns></returns>
	static int InitLineIterator(IntPtr image, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, IntPtr line_iterator, PixelConnectType connectivity)
	{
		return cvInitLineIterator((CvArr*)image.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, (CvLineIterator*)line_iterator.ToPointer(), (int)connectivity);
	}

	/// <summary>
	/// Initializes line iterator. Initially, line_iterator->ptr will point
	/// to pt1 (or pt2, see left_to_right description) location in the image.
	/// Returns the number of pixels on the line between the ending points.
	/// </summary>
	/// <param name="image"></param>
	/// <param name="pt1"></param>
	/// <param name="pt2"></param>
	/// <returns></returns>
	static int InitLineIterator(IntPtr image, NAMESPACE::Point2D32s pt1, NAMESPACE::Point2D32s pt2, IntPtr line_iterator)
	{
		return cvInitLineIterator((CvArr*)image.ToPointer(), *(CvPoint*)&pt1, *(CvPoint*)&pt2, (CvLineIterator*)line_iterator.ToPointer());
	}

	/// <summary>
	/// Initializes font structure used further in cvPutText
	/// </summary>
	/// <param name="font"></param>
	/// <param name="font_face"></param>
	/// <param name="hscale"></param>
	/// <param name="vscale"></param>
	/// <param name="shear"></param>
	/// <param name="thickness"></param>
	static void InitFont(IntPtr font, FontFlag font_face, double hscale, double vscale, double shear, int thickness, LineTypeFlag line_type)
	{
		cvInitFont((CvFont*)font.ToPointer(), (int)font_face, hscale, vscale, shear, thickness, (int)line_type);
	}

	/// <summary>
	/// Initializes font structure used further in cvPutText
	/// </summary>
	/// <param name="font"></param>
	/// <param name="font_face"></param>
	/// <param name="hscale"></param>
	/// <param name="vscale"></param>
	/// <param name="shear"></param>
	static void InitFont(IntPtr font, FontFlag font_face, double hscale, double vscale, double shear, int thickness)
	{
		cvInitFont((CvFont*)font.ToPointer(), (int)font_face, hscale, vscale, shear, thickness);
	}

	/// <summary>
	/// Initializes font structure used further in cvPutText
	/// </summary>
	/// <param name="font"></param>
	/// <param name="font_face"></param>
	/// <param name="hscale"></param>
	/// <param name="vscale"></param>
	static void InitFont(IntPtr font, FontFlag font_face, double hscale, double vscale, double shear)
	{
		cvInitFont((CvFont*)font.ToPointer(), (int)font_face, hscale, vscale, shear);
	}

	/// <summary>
	/// Initializes font structure used further in cvPutText
	/// </summary>
	/// <param name="font"></param>
	/// <param name="font_face"></param>
	/// <param name="hscale"></param>
	static void InitFont(IntPtr font, FontFlag font_face, double hscale, double vscale)
	{
		cvInitFont((CvFont*)font.ToPointer(), (int)font_face, hscale, vscale);
	}

	/// <summary>
	/// Renders text stroke with specified font and color at specified location.
	/// CvFont should be initialized with cvInitFont
	/// </summary>
	/// <param name="img"></param>
	/// <param name="text"></param>
	/// <param name="org"></param>
	/// <param name="font"></param>
	static void PutText(IntPtr img, IntPtr text, NAMESPACE::Point2D32s org, IntPtr font, NAMESPACE::Scalar color)
	{
		cvPutText((CvArr*)img.ToPointer(), (char*)text.ToPointer(), *(CvPoint*)&org, (CvFont*)font.ToPointer(), *(CvScalar*)&color);
	}

	/// <summary>
	/// Calculates bounding box of text stroke (useful for alignment)
	/// </summary>
	/// <param name="text_string"></param>
	/// <param name="font"></param>
	/// <param name="text_size"></param>
	static void GetTextSize(IntPtr text_string, IntPtr font, IntPtr text_size, IntPtr baseline)
	{
		cvGetTextSize((char*)text_string.ToPointer(), (CvFont*)font.ToPointer(), (CvSize*)text_size.ToPointer(), (int*)baseline.ToPointer());
	}

	/// <summary>
	/// Unpacks color value, if arrtype is CV_8UC?, <color> is treated as
	/// packed color value, otherwise the first channels (depending on arrtype)
	/// of destination scalar are set to the same value = <color>
	/// </summary>
	/// <param name="packed_color"></param>
	/// <returns></returns>
	static NAMESPACE::Scalar ColorToScalar(double packed_color, int arrtype)
	{
		return *(NAMESPACE::Scalar*)&cvColorToScalar(packed_color, arrtype);
	}

	/// <summary>
	/// Returns the polygon points which make up the given ellipse.  The ellipse is define by
	/// the box of size 'axes' rotated 'angle' around the 'center'.  A partial sweep
	/// of the ellipse arc can be done by spcifying arc_start and arc_end to be something
	/// other than 0 and 360, respectively.  The input array 'pts' must be large enough to
	/// hold the result.  The total number of points stored into 'pts' is returned by this
	/// function.
	/// </summary>
	/// <param name="center"></param>
	/// <param name="axes"></param>
	/// <param name="angle"></param>
	/// <param name="arc_start"></param>
	/// <param name="arc_end"></param>
	/// <param name="pts"></param>
	/// <returns></returns>
	static int Ellipse2Poly(NAMESPACE::Point2D32s center, NAMESPACE::Size2D32s axes, int angle, int arc_start, int arc_end, IntPtr pts, int delta)
	{
		return cvEllipse2Poly(*(CvPoint*)&center, *(CvSize*)&axes, angle, arc_start, arc_end, (CvPoint*)pts.ToPointer(), delta);
	}

	/// <summary>
	/// Draws contour outlines or filled interiors on the image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="contour"></param>
	/// <param name="external_color"></param>
	/// <param name="hole_color"></param>
	/// <param name="max_level"></param>
	/// <param name="thickness"></param>
	/// <param name="line_type"></param>
	static void DrawContours(IntPtr img, IntPtr contour, NAMESPACE::Scalar external_color, NAMESPACE::Scalar hole_color, int max_level, int thickness, LineTypeFlag line_type, NAMESPACE::Point2D32s offset)
	{
		cvDrawContours((CvArr*)img.ToPointer(), (CvSeq*)contour.ToPointer(), *(CvScalar*)&external_color, *(CvScalar*)&hole_color, max_level, thickness, (int)line_type, *(CvPoint*)&offset);
	}

	/// <summary>
	/// Draws contour outlines or filled interiors on the image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="contour"></param>
	/// <param name="external_color"></param>
	/// <param name="hole_color"></param>
	/// <param name="max_level"></param>
	/// <param name="thickness"></param>
	static void DrawContours(IntPtr img, IntPtr contour, NAMESPACE::Scalar external_color, NAMESPACE::Scalar hole_color, int max_level, int thickness, LineTypeFlag line_type)
	{
		cvDrawContours((CvArr*)img.ToPointer(), (CvSeq*)contour.ToPointer(), *(CvScalar*)&external_color, *(CvScalar*)&hole_color, max_level, thickness, (int)line_type);
	}

	/// <summary>
	/// Draws contour outlines or filled interiors on the image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="contour"></param>
	/// <param name="external_color"></param>
	/// <param name="hole_color"></param>
	/// <param name="max_level"></param>
	static void DrawContours(IntPtr img, IntPtr contour, NAMESPACE::Scalar external_color, NAMESPACE::Scalar hole_color, int max_level, int thickness)
	{
		cvDrawContours((CvArr*)img.ToPointer(), (CvSeq*)contour.ToPointer(), *(CvScalar*)&external_color, *(CvScalar*)&hole_color, max_level, thickness);
	}

	/// <summary>
	/// Draws contour outlines or filled interiors on the image
	/// </summary>
	/// <param name="img"></param>
	/// <param name="contour"></param>
	/// <param name="external_color"></param>
	/// <param name="hole_color"></param>
	static void DrawContours(IntPtr img, IntPtr contour, NAMESPACE::Scalar external_color, NAMESPACE::Scalar hole_color, int max_level)
	{
		cvDrawContours((CvArr*)img.ToPointer(), (CvSeq*)contour.ToPointer(), *(CvScalar*)&external_color, *(CvScalar*)&hole_color, max_level);
	}

	/// <summary>
	/// Does look-up transformation. Elements of the source array
	/// (that should be 8uC1 or 8sC1) are used as indexes in lutarr 256-element table
	/// </summary>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void LUT(IntPtr src, IntPtr dst, IntPtr lut)
	{
		cvLUT((CvArr*)src.ToPointer(), (CvArr*)dst.ToPointer(), (CvArr*)lut.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="tree_iterator"></param>
	/// <param name="first"></param>
	static void InitTreeNodeIterator(IntPtr tree_iterator, IntPtr first, int max_level)
	{
		cvInitTreeNodeIterator((CvTreeNodeIterator*)tree_iterator.ToPointer(), (void*)first.ToPointer(), max_level);
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static IntPtr NextTreeNode(IntPtr tree_iterator)
	{
		return IntPtr(cvNextTreeNode((CvTreeNodeIterator*)tree_iterator.ToPointer()));
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static IntPtr PrevTreeNode(IntPtr tree_iterator)
	{
		return IntPtr(cvPrevTreeNode((CvTreeNodeIterator*)tree_iterator.ToPointer()));
	}

	/// <summary>
	/// Inserts sequence into tree with specified "parent" sequence.
	/// If parent is equal to frame (e.g. the most external contour),
	/// then added contour will have null pointer to parent.
	/// </summary>
	/// <param name="node"></param>
	/// <param name="parent"></param>
	static void InsertNodeIntoTree(IntPtr node, IntPtr parent, IntPtr frame)
	{
		cvInsertNodeIntoTree((void*)node.ToPointer(), (void*)parent.ToPointer(), (void*)frame.ToPointer());
	}

	/// <summary>
	/// Removes contour from tree (together with the contour children).
	/// </summary>
	/// <param name="node"></param>
	static void RemoveNodeFromTree(IntPtr node, IntPtr frame)
	{
		cvRemoveNodeFromTree((void*)node.ToPointer(), (void*)frame.ToPointer());
	}

	/// <summary>
	/// Gathers pointers to all the sequences,
	/// accessible from the <first>, to the single sequence
	/// </summary>
	/// <param name="first"></param>
	/// <param name="header_size"></param>
	/// <returns></returns>
	static IntPtr TreeToNodeSeq(IntPtr first, int header_size, IntPtr storage)
	{
		return IntPtr(cvTreeToNodeSeq((void*)first.ToPointer(), header_size, (CvMemStorage*)storage.ToPointer()));
	}

	/// <summary>
	/// </summary>
	/// <param name="samples"></param>
	/// <param name="cluster_count"></param>
	/// <param name="labels"></param>
	/// <param name="termcrit"></param>
	/// <param name="attempts"></param>
	/// <param name="rng"></param>
	/// <param name="flags"></param>
	/// <param name="_centers"></param>
	/// <returns></returns>
	static int KMeans2(IntPtr samples, int cluster_count, IntPtr labels, NAMESPACE::TermCriteria termcrit, int attempts, IntPtr rng, KMeansFlag flags, IntPtr _centers, IntPtr compactness)
	{
		return cvKMeans2((CvArr*)samples.ToPointer(), cluster_count, (CvArr*)labels.ToPointer(), *(CvTermCriteria*)&termcrit, attempts, (CvRNG*)rng.ToPointer(), (int)flags, (CvArr*)_centers.ToPointer(), (double*)compactness.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="samples"></param>
	/// <param name="cluster_count"></param>
	/// <param name="labels"></param>
	/// <param name="termcrit"></param>
	/// <param name="attempts"></param>
	/// <param name="rng"></param>
	/// <param name="flags"></param>
	/// <returns></returns>
	static int KMeans2(IntPtr samples, int cluster_count, IntPtr labels, NAMESPACE::TermCriteria termcrit, int attempts, IntPtr rng, KMeansFlag flags, IntPtr _centers)
	{
		return cvKMeans2((CvArr*)samples.ToPointer(), cluster_count, (CvArr*)labels.ToPointer(), *(CvTermCriteria*)&termcrit, attempts, (CvRNG*)rng.ToPointer(), (int)flags, (CvArr*)_centers.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="samples"></param>
	/// <param name="cluster_count"></param>
	/// <param name="labels"></param>
	/// <param name="termcrit"></param>
	/// <param name="attempts"></param>
	/// <param name="rng"></param>
	/// <returns></returns>
	static int KMeans2(IntPtr samples, int cluster_count, IntPtr labels, NAMESPACE::TermCriteria termcrit, int attempts, IntPtr rng, KMeansFlag flags)
	{
		return cvKMeans2((CvArr*)samples.ToPointer(), cluster_count, (CvArr*)labels.ToPointer(), *(CvTermCriteria*)&termcrit, attempts, (CvRNG*)rng.ToPointer(), (int)flags);
	}

	/// <summary>
	/// </summary>
	/// <param name="samples"></param>
	/// <param name="cluster_count"></param>
	/// <param name="labels"></param>
	/// <param name="termcrit"></param>
	/// <param name="attempts"></param>
	/// <returns></returns>
	static int KMeans2(IntPtr samples, int cluster_count, IntPtr labels, NAMESPACE::TermCriteria termcrit, int attempts, IntPtr rng)
	{
		return cvKMeans2((CvArr*)samples.ToPointer(), cluster_count, (CvArr*)labels.ToPointer(), *(CvTermCriteria*)&termcrit, attempts, (CvRNG*)rng.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="samples"></param>
	/// <param name="cluster_count"></param>
	/// <param name="labels"></param>
	/// <param name="termcrit"></param>
	/// <returns></returns>
	static int KMeans2(IntPtr samples, int cluster_count, IntPtr labels, NAMESPACE::TermCriteria termcrit, int attempts)
	{
		return cvKMeans2((CvArr*)samples.ToPointer(), cluster_count, (CvArr*)labels.ToPointer(), *(CvTermCriteria*)&termcrit, attempts);
	}

	/// <summary>
	/// </summary>
	/// <param name="samples"></param>
	/// <param name="cluster_count"></param>
	/// <param name="labels"></param>
	/// <returns></returns>
	static int KMeans2(IntPtr samples, int cluster_count, IntPtr labels, NAMESPACE::TermCriteria termcrit)
	{
		return cvKMeans2((CvArr*)samples.ToPointer(), cluster_count, (CvArr*)labels.ToPointer(), *(CvTermCriteria*)&termcrit);
	}

	/// <summary>
	/// Add the function pointers table with associated information to the IPP primitives list
	/// </summary>
	/// <returns></returns>
	static int RegisterModule(IntPtr module_info)
	{
		return cvRegisterModule((CvModuleInfo*)module_info.ToPointer());
	}

	/// <summary>
	/// Loads optimized functions from IPP, MKL etc. or switches back to pure C code
	/// </summary>
	/// <returns></returns>
	static int UseOptimized(int on_off)
	{
		return cvUseOptimized(on_off);
	}

	/// <summary>
	/// Retrieves information about the registered modules and loaded optimized plugins
	/// </summary>
	/// <param name="module_name"></param>
	/// <param name="version"></param>
	static void GetModuleInfo(IntPtr module_name, IntPtr version, IntPtr loaded_addon_plugins)
	{
		cvGetModuleInfo((char*)module_name.ToPointer(), (const char**)version.ToPointer(), (const char**)loaded_addon_plugins.ToPointer());
	}

	/// <summary>
	/// Get current OpenCV error status
	/// </summary>
	/// <returns></returns>
	static ErrorCode GetErrStatus()
	{
		return (ErrorCode)cvGetErrStatus();
	}

	/// <summary>
	/// Sets error status silently
	/// </summary>
	static void SetErrStatus(ErrorCode status)
	{
		cvSetErrStatus((int)status);
	}

	/// <summary>
	/// Retrives current error processing mode
	/// </summary>
	/// <returns></returns>
	static ErrorMode GetErrMode()
	{
		return (ErrorMode)cvGetErrMode();
	}

	/// <summary>
	/// Sets error processing mode, returns previously used mode
	/// </summary>
	/// <returns></returns>
	static int SetErrMode(ErrorMode mode)
	{
		return cvSetErrMode((int)mode);
	}

	/// <summary>
	/// Sets error status and performs some additonal actions (displaying message box,
	/// writing message to stderr, terminating application etc.)
	/// depending on the current error mode
	/// </summary>
	/// <param name="status"></param>
	/// <param name="func_name"></param>
	/// <param name="err_msg"></param>
	/// <param name="file_name"></param>
	static void Error(int status, IntPtr func_name, IntPtr err_msg, IntPtr file_name, int line)
	{
		cvError(status, (char*)func_name.ToPointer(), (char*)err_msg.ToPointer(), (char*)file_name.ToPointer(), line);
	}

	/// <summary>
	/// Retrieves textual description of the error given its code
	/// </summary>
	/// <returns></returns>
	static IntPtr ErrorStr(ErrorCode status)
	{
		return IntPtr((void*)cvErrorStr((int)status));
	}

	/// <summary>
	/// Retrieves detailed information about the last error occured
	/// </summary>
	/// <param name="errcode_desc"></param>
	/// <param name="description"></param>
	/// <param name="filename"></param>
	/// <returns></returns>
	static int GetErrInfo(IntPtr errcode_desc, IntPtr description, IntPtr filename, IntPtr line)
	{
		return cvGetErrInfo((const char**)errcode_desc.ToPointer(), (const char**)description.ToPointer(), (const char**)filename.ToPointer(), (int*)line.ToPointer());
	}

	/// <summary>
	/// Maps IPP error codes to the counterparts from OpenCV
	/// </summary>
	/// <returns></returns>
	static ErrorCode ErrorFromIppStatus(int ipp_status)
	{
		return (ErrorCode)cvErrorFromIppStatus(ipp_status);
	}

	/// <summary>
	/// Assigns a new error-handling function
	/// </summary>
	/// <param name="error_handler"></param>
	/// <param name="userdata"></param>
	/// <returns></returns>
	static IntPtr RedirectError(ErrorCallback^ error_handler, IntPtr userdata, IntPtr prev_userdata)
	{
		return IntPtr(cvRedirectError((CvErrorCallback)Marshal::GetFunctionPointerForDelegate(error_handler).ToPointer(), (void*)userdata.ToPointer(), (void**)prev_userdata.ToPointer()));
	}

	/// <summary>
	/// Assigns a new error-handling function
	/// </summary>
	/// <param name="error_handler"></param>
	/// <returns></returns>
	static IntPtr RedirectError(ErrorCallback^ error_handler, IntPtr userdata)
	{
		return IntPtr(cvRedirectError((CvErrorCallback)Marshal::GetFunctionPointerForDelegate(error_handler).ToPointer(), (void*)userdata.ToPointer()));
	}

	/// <summary>
	/// Assigns a new error-handling function
	/// </summary>
	/// <returns></returns>
	static IntPtr RedirectError(ErrorCallback^ error_handler)
	{
		return IntPtr(cvRedirectError((CvErrorCallback)Marshal::GetFunctionPointerForDelegate(error_handler).ToPointer()));
	}

	/// <summary>
	/// Output to:
	/// cvNulDevReport - nothing
	/// cvStdErrReport - console(fprintf(stderr,...))
	/// cvGuiBoxReport - MessageBox(WIN32)
	/// </summary>
	/// <param name="status"></param>
	/// <param name="func_name"></param>
	/// <param name="err_msg"></param>
	/// <param name="file_name"></param>
	/// <param name="line"></param>
	/// <returns></returns>
	static int NulDevReport(int status, IntPtr func_name, IntPtr err_msg, IntPtr file_name, int line, IntPtr userdata)
	{
		return cvNulDevReport(status, (char*)func_name.ToPointer(), (char*)err_msg.ToPointer(), (char*)file_name.ToPointer(), line, (void*)userdata.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="status"></param>
	/// <param name="func_name"></param>
	/// <param name="err_msg"></param>
	/// <param name="file_name"></param>
	/// <param name="line"></param>
	/// <returns></returns>
	static int StdErrReport(int status, IntPtr func_name, IntPtr err_msg, IntPtr file_name, int line, IntPtr userdata)
	{
		return cvStdErrReport(status, (char*)func_name.ToPointer(), (char*)err_msg.ToPointer(), (char*)file_name.ToPointer(), line, (void*)userdata.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="status"></param>
	/// <param name="func_name"></param>
	/// <param name="err_msg"></param>
	/// <param name="file_name"></param>
	/// <param name="line"></param>
	/// <returns></returns>
	static int GuiBoxReport(int status, IntPtr func_name, IntPtr err_msg, IntPtr file_name, int line, IntPtr userdata)
	{
		return cvGuiBoxReport(status, (char*)func_name.ToPointer(), (char*)err_msg.ToPointer(), (char*)file_name.ToPointer(), line, (void*)userdata.ToPointer());
	}

	/// <summary>
	/// Set user-defined memory managment functions (substitutors for malloc and free) that
	/// will be called by cvAlloc, cvFree and higher-level functions (e.g. cvCreateImage)
	/// </summary>
	/// <param name="alloc_func"></param>
	/// <param name="free_func"></param>
	static void SetMemoryManager(AllocFunc^ alloc_func, FreeFunc^ free_func, IntPtr userdata)
	{
		cvSetMemoryManager((CvAllocFunc)Marshal::GetFunctionPointerForDelegate(alloc_func).ToPointer(), 
			(CvFreeFunc)Marshal::GetFunctionPointerForDelegate(free_func).ToPointer(), (void*)userdata.ToPointer());
	}

	/// <summary>
	/// Set user-defined memory managment functions (substitutors for malloc and free) that
	/// will be called by cvAlloc, cvFree and higher-level functions (e.g. cvCreateImage)
	/// </summary>
	/// <param name="alloc_func"></param>
	static void SetMemoryManager(AllocFunc^ alloc_func, FreeFunc^ free_func)
	{
		cvSetMemoryManager((CvAllocFunc)Marshal::GetFunctionPointerForDelegate(alloc_func).ToPointer(), 
			(CvFreeFunc)Marshal::GetFunctionPointerForDelegate(free_func).ToPointer());
	}

	/// <summary>
	/// Set user-defined memory managment functions (substitutors for malloc and free) that
	/// will be called by cvAlloc, cvFree and higher-level functions (e.g. cvCreateImage)
	/// </summary>
	static void SetMemoryManager(AllocFunc^ alloc_func)
	{
		cvSetMemoryManager((CvAllocFunc)Marshal::GetFunctionPointerForDelegate(alloc_func).ToPointer());
	}

	/// <summary>
	/// Set user-defined memory managment functions (substitutors for malloc and free) that
	/// will be called by cvAlloc, cvFree and higher-level functions (e.g. cvCreateImage)
	/// </summary>
	static void SetMemoryManager()
	{
		cvSetMemoryManager();
	}

	/// <summary>
	/// Makes OpenCV use IPL functions for IplImage allocation/deallocation
	/// </summary>
	/// <param name="create_header"></param>
	/// <param name="allocate_data"></param>
	/// <param name="deallocate"></param>
	/// <param name="create_roi"></param>
	static void SetIPLAllocators(IplCreateImageHeader^ create_header, IplAllocateImageData^ allocate_data, IplDeallocate^ deallocate, IplCreateROI^ create_roi, IplCloneImage^ clone_image)
	{
		cvSetIPLAllocators(
			(Cv_iplCreateImageHeader)Marshal::GetFunctionPointerForDelegate(create_header).ToPointer(), 
			(Cv_iplAllocateImageData)Marshal::GetFunctionPointerForDelegate(allocate_data).ToPointer(), 
			(Cv_iplDeallocate)Marshal::GetFunctionPointerForDelegate(deallocate).ToPointer(), 
			(Cv_iplCreateROI)Marshal::GetFunctionPointerForDelegate(create_roi).ToPointer(), 
			(Cv_iplCloneImage)Marshal::GetFunctionPointerForDelegate(clone_image).ToPointer());
	}

	/// <summary>
	/// opens existing or creates new file storage
	/// </summary>
	/// <param name="filename"></param>
	/// <param name="memstorage"></param>
	/// <returns></returns>
	static IntPtr OpenFileStorage(IntPtr filename, IntPtr memstorage, int flags)
	{
		return IntPtr(cvOpenFileStorage((char*)filename.ToPointer(), (CvMemStorage*)memstorage.ToPointer(), flags));
	}

	/// <summary>
	/// closes file storage and deallocates buffers
	/// </summary>
	static void ReleaseFileStorage(IntPtr fs)
	{
		cvReleaseFileStorage((CvFileStorage**)fs.ToPointer());
	}

	/// <summary>
	/// returns attribute value or 0 (NULL) if there is no such attribute
	/// </summary>
	/// <param name="attr"></param>
	/// <returns></returns>
	static IntPtr AttrValue(IntPtr attr, IntPtr attr_name)
	{
		return IntPtr((void*)cvAttrValue((CvAttrList*)attr.ToPointer(), (char*)attr_name.ToPointer()));
	}

	/// <summary>
	/// starts writing compound structure (map or sequence)
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	/// <param name="struct_flags"></param>
	/// <param name="type_name"></param>
	static void StartWriteStruct(IntPtr fs, IntPtr name, int struct_flags, IntPtr type_name, CvAttrList attributes)
	{
		cvStartWriteStruct((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), struct_flags, (char*)type_name.ToPointer(), attributes);
	}

	/// <summary>
	/// starts writing compound structure (map or sequence)
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	/// <param name="struct_flags"></param>
	static void StartWriteStruct(IntPtr fs, IntPtr name, int struct_flags, IntPtr type_name)
	{
		cvStartWriteStruct((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), struct_flags, (char*)type_name.ToPointer());
	}

	/// <summary>
	/// starts writing compound structure (map or sequence)
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	static void StartWriteStruct(IntPtr fs, IntPtr name, int struct_flags)
	{
		cvStartWriteStruct((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), struct_flags);
	}

	/// <summary>
	/// finishes writing compound structure
	/// </summary>
	static void EndWriteStruct(IntPtr fs)
	{
		cvEndWriteStruct((CvFileStorage*)fs.ToPointer());
	}

	/// <summary>
	/// writes an integer
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	static void WriteInt(IntPtr fs, IntPtr name, int value)
	{
		cvWriteInt((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), value);
	}

	/// <summary>
	/// writes a floating-point number
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	static void WriteReal(IntPtr fs, IntPtr name, double value)
	{
		cvWriteReal((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), value);
	}

	/// <summary>
	/// writes a string
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	/// <param name="str"></param>
	static void WriteString(IntPtr fs, IntPtr name, IntPtr str, int quote)
	{
		cvWriteString((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), (char*)str.ToPointer(), quote);
	}

	/// <summary>
	/// writes a string
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	static void WriteString(IntPtr fs, IntPtr name, IntPtr str)
	{
		cvWriteString((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), (char*)str.ToPointer());
	}

	/// <summary>
	/// writes a comment
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="comment"></param>
	static void WriteComment(IntPtr fs, IntPtr comment, int eol_comment)
	{
		cvWriteComment((CvFileStorage*)fs.ToPointer(), (char*)comment.ToPointer(), eol_comment);
	}

	/// <summary>
	/// writes instance of a standard type (matrix, image, sequence, graph etc.)
	/// or user-defined type
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	/// <param name="ptr"></param>
	static void Write(IntPtr fs, IntPtr name, IntPtr ptr, CvAttrList attributes)
	{
		cvWrite((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), (void*)ptr.ToPointer(), attributes);
	}

	/// <summary>
	/// writes instance of a standard type (matrix, image, sequence, graph etc.)
	/// or user-defined type
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	static void Write(IntPtr fs, IntPtr name, IntPtr ptr)
	{
		cvWrite((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), (void*)ptr.ToPointer());
	}

	/// <summary>
	/// starts the next stream
	/// </summary>
	static void StartNextStream(IntPtr fs)
	{
		cvStartNextStream((CvFileStorage*)fs.ToPointer());
	}

	/// <summary>
	/// helper function: writes multiple integer or floating-point numbers
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="src"></param>
	/// <param name="len"></param>
	static void WriteRawData(IntPtr fs, IntPtr src, int len, IntPtr dt)
	{
		cvWriteRawData((CvFileStorage*)fs.ToPointer(), (void*)src.ToPointer(), len, (char*)dt.ToPointer());
	}

	/// <summary>
	/// returns the hash entry corresponding to the specified literal key string or 0
	/// if there is no such a key in the storage
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	/// <param name="len"></param>
	/// <returns></returns>
	static IntPtr GetHashedKey(IntPtr fs, IntPtr name, int len, int create_missing)
	{
		return IntPtr(cvGetHashedKey((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), len, create_missing));
	}

	/// <summary>
	/// returns the hash entry corresponding to the specified literal key string or 0
	/// if there is no such a key in the storage
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="name"></param>
	/// <returns></returns>
	static IntPtr GetHashedKey(IntPtr fs, IntPtr name, int len)
	{
		return IntPtr(cvGetHashedKey((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer(), len));
	}

	/// <summary>
	/// returns the hash entry corresponding to the specified literal key string or 0
	/// if there is no such a key in the storage
	/// </summary>
	/// <param name="fs"></param>
	/// <returns></returns>
	static IntPtr GetHashedKey(IntPtr fs, IntPtr name)
	{
		return IntPtr(cvGetHashedKey((CvFileStorage*)fs.ToPointer(), (char*)name.ToPointer()));
	}

	/// <summary>
	/// returns file node with the specified key within the specified map
	/// (collection of named nodes)
	/// </summary>
	/// <param name="fs"></param>
	/// <returns></returns>
	static IntPtr GetRootFileNode(IntPtr fs, int stream_index)
	{
		return IntPtr(cvGetRootFileNode((CvFileStorage*)fs.ToPointer(), stream_index));
	}

	/// <summary>
	/// returns file node with the specified key within the specified map
	/// (collection of named nodes)
	/// </summary>
	/// <returns></returns>
	static IntPtr GetRootFileNode(IntPtr fs)
	{
		return IntPtr(cvGetRootFileNode((CvFileStorage*)fs.ToPointer()));
	}

	/// <summary>
	/// returns file node with the specified key within the specified map
	/// (collection of named nodes)
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="map"></param>
	/// <param name="key"></param>
	/// <returns></returns>
	static IntPtr GetFileNode(IntPtr fs, IntPtr map, IntPtr key, int create_missing)
	{
		return IntPtr(cvGetFileNode((CvFileStorage*)fs.ToPointer(), (CvFileNode*)map.ToPointer(), (CvStringHashNode*)key.ToPointer(), create_missing));
	}

	/// <summary>
	/// returns file node with the specified key within the specified map
	/// (collection of named nodes)
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="map"></param>
	/// <returns></returns>
	static IntPtr GetFileNode(IntPtr fs, IntPtr map, IntPtr key)
	{
		return IntPtr(cvGetFileNode((CvFileStorage*)fs.ToPointer(), (CvFileNode*)map.ToPointer(), (CvStringHashNode*)key.ToPointer()));
	}

	/// <summary>
	/// this is a slower version of cvGetFileNode that takes the key as a literal string
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="map"></param>
	/// <returns></returns>
	static IntPtr GetFileNodeByName(IntPtr fs, IntPtr map, IntPtr name)
	{
		return IntPtr(cvGetFileNodeByName((CvFileStorage*)fs.ToPointer(), (CvFileNode*)map.ToPointer(), (char*)name.ToPointer()));
	}

	/// <summary>
	/// decodes standard or user-defined object and returns it
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="node"></param>
	/// <returns></returns>
	static IntPtr Read(IntPtr fs, IntPtr node, IntPtr attributes)
	{
		return IntPtr(cvRead((CvFileStorage*)fs.ToPointer(), (CvFileNode*)node.ToPointer(), (CvAttrList*)attributes.ToPointer()));
	}

	/// <summary>
	/// decodes standard or user-defined object and returns it
	/// </summary>
	/// <param name="fs"></param>
	/// <returns></returns>
	static IntPtr Read(IntPtr fs, IntPtr node)
	{
		return IntPtr(cvRead((CvFileStorage*)fs.ToPointer(), (CvFileNode*)node.ToPointer()));
	}

	/// <summary>
	/// starts reading data from sequence or scalar numeric node
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="src"></param>
	static void StartReadRawData(IntPtr fs, IntPtr src, IntPtr reader)
	{
		cvStartReadRawData((CvFileStorage*)fs.ToPointer(), (CvFileNode*)src.ToPointer(), (CvSeqReader*)reader.ToPointer());
	}

	/// <summary>
	/// reads multiple numbers and stores them to array
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="reader"></param>
	/// <param name="count"></param>
	/// <param name="dst"></param>
	static void ReadRawDataSlice(IntPtr fs, IntPtr reader, int count, IntPtr dst, IntPtr dt)
	{
		cvReadRawDataSlice((CvFileStorage*)fs.ToPointer(), (CvSeqReader*)reader.ToPointer(), count, (void*)dst.ToPointer(), (char*)dt.ToPointer());
	}

	/// <summary>
	/// combination of two previous functions for easier reading of whole sequences
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="src"></param>
	/// <param name="dst"></param>
	static void ReadRawData(IntPtr fs, IntPtr src, IntPtr dst, IntPtr dt)
	{
		cvReadRawData((CvFileStorage*)fs.ToPointer(), (CvFileNode*)src.ToPointer(), (void*)dst.ToPointer(), (char*)dt.ToPointer());
	}

	/// <summary>
	/// writes a copy of file node to file storage
	/// </summary>
	/// <param name="fs"></param>
	/// <param name="new_node_name"></param>
	/// <param name="node"></param>
	static void WriteFileNode(IntPtr fs, IntPtr new_node_name, IntPtr node, int embed)
	{
		cvWriteFileNode((CvFileStorage*)fs.ToPointer(), (char*)new_node_name.ToPointer(), (CvFileNode*)node.ToPointer(), embed);
	}

	/// <summary>
	/// returns name of file node
	/// </summary>
	/// <returns></returns>
	static IntPtr GetFileNodeName(IntPtr node)
	{
		return IntPtr((void*)cvGetFileNodeName((CvFileNode*)node.ToPointer()));
	}

	/// <summary>
	/// Adding own types
	/// </summary>
	static void RegisterType(IntPtr info)
	{
		cvRegisterType((CvTypeInfo*)info.ToPointer());
	}

	/// <summary>
	/// UnregisterType
	/// </summary>
	static void UnregisterType(IntPtr type_name)
	{
		cvUnregisterType((char*)type_name.ToPointer());
	}

	/// <summary>
	/// FirstType
	/// </summary>
	/// <returns></returns>
	static IntPtr FirstType()
	{
		return IntPtr(cvFirstType());
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static IntPtr FindType(IntPtr type_name)
	{
		return IntPtr(cvFindType((char*)type_name.ToPointer()));
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static IntPtr TypeOf(IntPtr struct_ptr)
	{
		return IntPtr(cvTypeOf((void*)struct_ptr.ToPointer()));
	}

	/// <summary>
	/// universal functions
	/// </summary>
	static void Release(IntPtr struct_ptr)
	{
		cvRelease((void**)struct_ptr.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static IntPtr Clone(IntPtr struct_ptr)
	{
		return IntPtr(cvClone((void*)struct_ptr.ToPointer()));
	}

	/// <summary>
	/// simple API for reading/writing data
	/// </summary>
	/// <param name="filename"></param>
	/// <param name="struct_ptr"></param>
	/// <param name="name"></param>
	/// <param name="comment"></param>
	static void Save(IntPtr filename, IntPtr struct_ptr, IntPtr name, IntPtr comment, CvAttrList attributes)
	{
		cvSave((char*)filename.ToPointer(), (void*)struct_ptr.ToPointer(), (char*)name.ToPointer(), (char*)comment.ToPointer(), attributes);
	}

	/// <summary>
	/// simple API for reading/writing data
	/// </summary>
	/// <param name="filename"></param>
	/// <param name="struct_ptr"></param>
	/// <param name="name"></param>
	static void Save(IntPtr filename, IntPtr struct_ptr, IntPtr name, IntPtr comment)
	{
		cvSave((char*)filename.ToPointer(), (void*)struct_ptr.ToPointer(), (char*)name.ToPointer(), (char*)comment.ToPointer());
	}

	/// <summary>
	/// simple API for reading/writing data
	/// </summary>
	/// <param name="filename"></param>
	/// <param name="struct_ptr"></param>
	static void Save(IntPtr filename, IntPtr struct_ptr, IntPtr name)
	{
		cvSave((char*)filename.ToPointer(), (void*)struct_ptr.ToPointer(), (char*)name.ToPointer());
	}

	/// <summary>
	/// simple API for reading/writing data
	/// </summary>
	/// <param name="filename"></param>
	static void Save(IntPtr filename, IntPtr struct_ptr)
	{
		cvSave((char*)filename.ToPointer(), (void*)struct_ptr.ToPointer());
	}

	/// <summary>
	/// </summary>
	/// <param name="filename"></param>
	/// <param name="memstorage"></param>
	/// <param name="name"></param>
	/// <returns></returns>
	static IntPtr Load(IntPtr filename, IntPtr memstorage, IntPtr name, IntPtr real_name)
	{
		return IntPtr(cvLoad((char*)filename.ToPointer(), (CvMemStorage*)memstorage.ToPointer(), (char*)name.ToPointer(), (const char**)real_name.ToPointer()));
	}

	/// <summary>
	/// </summary>
	/// <param name="filename"></param>
	/// <param name="memstorage"></param>
	/// <returns></returns>
	static IntPtr Load(IntPtr filename, IntPtr memstorage, IntPtr name)
	{
		return IntPtr(cvLoad((char*)filename.ToPointer(), (CvMemStorage*)memstorage.ToPointer(), (char*)name.ToPointer()));
	}

	/// <summary>
	/// </summary>
	/// <param name="filename"></param>
	/// <returns></returns>
	static IntPtr Load(IntPtr filename, IntPtr memstorage)
	{
		return IntPtr(cvLoad((char*)filename.ToPointer(), (CvMemStorage*)memstorage.ToPointer()));
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static IntPtr Load(IntPtr filename)
	{
		return IntPtr(cvLoad((char*)filename.ToPointer()));
	}

	/// <summary>
	/// helper functions for RNG initialization and accurate time measurement:
	/// uses internal clock counter on x86
	/// </summary>
	/// <returns></returns>
	static int64 GetTickCount()
	{
		return cvGetTickCount();
	}

	/// <summary>
	/// </summary>
	/// <returns></returns>
	static double GetTickFrequency()
	{
		return cvGetTickFrequency();
	}

	/// <summary>
	/// retrieve/set the number of threads used in OpenMP implementations
	/// </summary>
	/// <returns></returns>
	static int GetNumThreads()
	{
		return cvGetNumThreads();
	}

	/// <summary>
	/// </summary>
	static void SetNumThreads(int threads)
	{
		cvSetNumThreads(threads);
	}

	/// <summary>
	/// </summary>
	static void SetNumThreads()
	{
		cvSetNumThreads();
	}

	/// <summary>
	/// get index of the thread being executed
	/// </summary>
	/// <returns></returns>
	static int GetThreadNum()
	{
		return cvGetThreadNum();
	}

	/// <summary>
	/// </summary>
	/// <param name="_load_image"></param>
	/// <param name="_load_image_m"></param>
	/// <param name="_save_image"></param>
	/// <returns></returns>
	static int SetImageIOFunctions(LoadImageFunc^ _load_image, LoadImageMFunc^ _load_image_m, SaveImageFunc^ _save_image, ShowImageFunc^ _show_image)
	{
		return cvSetImageIOFunctions(
			(CvLoadImageFunc)Marshal::GetFunctionPointerForDelegate(_load_image).ToPointer(), 
			(CvLoadImageMFunc)Marshal::GetFunctionPointerForDelegate(_load_image_m).ToPointer(), 
			(CvSaveImageFunc)Marshal::GetFunctionPointerForDelegate(_save_image).ToPointer(), 
			(CvShowImageFunc)Marshal::GetFunctionPointerForDelegate(_show_image).ToPointer());
	}


//////////////////////////////////////////////////////////////////////////